diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index b1bccfc61ca..f517255f99e 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -23,7 +23,7 @@ jobs: steps: # Git Checkout - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: # Checkout the HEAD of the PR instead of the merge commit. ref: ${{ github.event.pull_request.head.sha }} @@ -38,7 +38,7 @@ jobs: id: ml # You can override MegaLinter flavor used to have faster performances # More info at https://megalinter.io/flavors/ - uses: oxsecurity/megalinter@v8.7.0 + uses: oxsecurity/megalinter@v8.8.0 env: # All available variables are described in documentation: # https://megalinter.io/configuration/ diff --git a/.github/workflows/o2-linter.yml b/.github/workflows/o2-linter.yml index 099209da6e6..ebc4c4d48bf 100644 --- a/.github/workflows/o2-linter.yml +++ b/.github/workflows/o2-linter.yml @@ -30,7 +30,7 @@ jobs: echo BRANCH_HEAD="$branch_head" >> "$GITHUB_ENV" echo BRANCH_BASE="$branch_base" >> "$GITHUB_ENV" - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ env.BRANCH_HEAD }} fetch-depth: 0 # needed to get the full history diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 24b650f65b5..d96f541d14a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -5,6 +5,7 @@ on: - cron: "0 0 * * *" permissions: + actions: write issues: write pull-requests: write diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index 15ac7939af2..8d59501d3be 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -144,6 +144,34 @@ void FastTracker::AddSiliconALICE3v2(std::vector pixelResolution) AddLayer("B10", 80., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); } +void FastTracker::AddSiliconALICE3(std::vector pixelResolution) +{ + float x0IT = 0.001; // 0.1% + float x0OT = 0.01; // 1.0% + float xrhoIB = 2.3292e-02; // 100 mum Si + float xrhoOT = 2.3292e-01; // 1000 mum Si + float eff = 1.00; + + float resRPhiIT = pixelResolution[0]; + float resZIT = pixelResolution[1]; + float resRPhiOT = pixelResolution[2]; + float resZOT = pixelResolution[3]; + + AddLayer("bpipe0", 0.48, 250, 0.00042, 2.772e-02, 0.0f, 0.0f, 0.0f, 0); // 150 mum Be + AddLayer("B00", 0.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1); + AddLayer("B01", 1.2, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1); + AddLayer("B02", 2.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1); + AddLayer("bpipe1", 3.7, 250, 0.0014, 9.24e-02, 0.0f, 0.0f, 0.0f, 0); // 500 mum Be + AddLayer("B03", 7., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B04", 9., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B05", 12., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B06", 20., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B07", 30., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B08", 45., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B09", 60., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); + AddLayer("B10", 80., 250, x0OT, xrhoOT, resRPhiOT, resZOT, eff, 1); +} + void FastTracker::AddTPC(float phiResMean, float zResMean) { LOG(info) << " Adding standard time projection chamber"; @@ -307,7 +335,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa break; } } - if (firstActiveLayer <= 0) { + if (firstActiveLayer < 0) { LOG(fatal) << "No active layers found in FastTracker, check layer setup"; return -2; // no active layers } diff --git a/ALICE3/Core/FastTracker.h b/ALICE3/Core/FastTracker.h index a0dba5d7ec5..c65c3206618 100644 --- a/ALICE3/Core/FastTracker.h +++ b/ALICE3/Core/FastTracker.h @@ -42,9 +42,11 @@ class FastTracker // Layer and layer configuration void AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi = 0.0f, float resZ = 0.0f, float eff = 0.0f, int type = 0); DetLayer GetLayer(const int layer, bool ignoreBarrelLayers = true) const; + std::vector GetLayers() const { return layers; } int GetLayerIndex(const std::string& name) const; size_t GetNLayers() const { return layers.size(); } bool IsLayerInert(const int layer) const { return layers[layer].isInert(); } + void ClearLayers() { layers.clear(); } void SetRadiationLength(const std::string layerName, float x0) { layers[GetLayerIndex(layerName)].setRadiationLength(x0); } void SetRadius(const std::string layerName, float r) { layers[GetLayerIndex(layerName)].setRadius(r); } void SetResolutionRPhi(const std::string layerName, float resRPhi) { layers[GetLayerIndex(layerName)].setResolutionRPhi(resRPhi); } @@ -57,6 +59,7 @@ class FastTracker void AddSiliconALICE3v4(std::vector pixelResolution); void AddSiliconALICE3v2(std::vector pixelResolution); + void AddSiliconALICE3(std::vector pixelResolution); void AddTPC(float phiResMean, float zResMean); void Print(); diff --git a/ALICE3/TableProducer/alice3-multicharmTable.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx index 3c81557082a..890b645bb51 100644 --- a/ALICE3/TableProducer/alice3-multicharmTable.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -162,7 +162,8 @@ struct alice3multicharmTable { Partition tracksPiFromXiC = ((aod::a3DecayMap::decayMap & trackSelectionPiFromXiC) == trackSelectionPiFromXiC) && aod::track::signed1Pt > 0.0f && 1.0f / nabs(aod::track::signed1Pt) > minPiCPt&& nabs(aod::track::dcaXY) > piFromXiC_dcaXYconstant + piFromXiC_dcaXYpTdep* nabs(aod::track::signed1Pt) && nabs(aod::track::dcaZ) > piFromXiC_dcaZconstant + piFromXiC_dcaZpTdep* nabs(aod::track::signed1Pt); - Partition tracksPiFromXiCC = ((aod::a3DecayMap::decayMap & trackSelectionPiFromXiCC) == trackSelectionPiFromXiCC) && aod::track::signed1Pt > 0.0f && 1.0f / nabs(aod::track::signed1Pt) > minPiCCPt&& nabs(aod::track::dcaXY) > piFromXiCC_dcaXYconstant + piFromXiCC_dcaXYpTdep* nabs(aod::track::signed1Pt); + Partition tracksPiFromXiCC = + ((aod::a3DecayMap::decayMap & trackSelectionPiFromXiCC) == trackSelectionPiFromXiCC) && aod::track::signed1Pt > 0.0f && 1.0f / nabs(aod::track::signed1Pt) > minPiCCPt&& nabs(aod::track::dcaXY) > piFromXiCC_dcaXYconstant + piFromXiCC_dcaXYpTdep* nabs(aod::track::signed1Pt) && nabs(aod::track::dcaZ) > piFromXiCC_dcaZconstant + piFromXiCC_dcaZpTdep* nabs(aod::track::signed1Pt); // Helper struct to pass candidate information struct { @@ -446,6 +447,13 @@ struct alice3multicharmTable { histos.add("hPi2cPt", "hPi2cPt", kTH1D, {axisPt}); histos.add("hPiccPt", "hPiccPt", kTH1D, {axisPt}); + histos.add("hPi1cDCAxy", "hPi1cDCAxy", kTH1D, {axisDCA}); + histos.add("hPi1cDCAz", "hPi1cDCAz", kTH1D, {axisDCA}); + histos.add("hPi2cDCAxy", "hPi2cDCAxy", kTH1D, {axisDCA}); + histos.add("hPi2cDCAz", "hPi2cDCAz", kTH1D, {axisDCA}); + histos.add("hPiccDCAxy", "hPiccDCAxy", kTH1D, {axisDCA}); + histos.add("hPiccDCAz", "hPiccDCAz", kTH1D, {axisDCA}); + histos.add("hMinXiDecayRadius", "hMinXiDecayRadius", kTH1D, {axisRadius2DXi}); histos.add("hMinXiCDecayRadius", "hMinXiCDecayRadius", kTH1D, {axisRadius}); histos.add("hMinXiCCDecayRadius", "hMinXiCCDecayRadius", kTH1D, {axisRadius}); @@ -780,6 +788,13 @@ struct alice3multicharmTable { piFromLa.pt(), piFromLa.eta(), piFromLa.dcaXY(), piFromLa.dcaZ(), pi1c.eta(), pi2c.eta(), picc.eta()); + + histos.fill(HIST("hPi1cDCAxy"), std::abs(pi1c.dcaXY() * 1e+4)); + histos.fill(HIST("hPi1cDCAz"), std::abs(pi1c.dcaZ() * 1e+4)); + histos.fill(HIST("hPi2cDCAxy"), std::abs(pi2c.dcaXY() * 1e+4)); + histos.fill(HIST("hPi2cDCAz"), std::abs(pi2c.dcaZ() * 1e+4)); + histos.fill(HIST("hPiccDCAxy"), std::abs(picc.dcaXY() * 1e+4)); + histos.fill(HIST("hPiccDCAz"), std::abs(picc.dcaZ() * 1e+4)); } } histos.fill(HIST("hCombinationsXiCC"), nCombinationsCC); diff --git a/ALICE3/Tasks/alice3-lutmaker.cxx b/ALICE3/Tasks/alice3-lutmaker.cxx index 50c03099468..4b57e462a8e 100644 --- a/ALICE3/Tasks/alice3-lutmaker.cxx +++ b/ALICE3/Tasks/alice3-lutmaker.cxx @@ -25,11 +25,11 @@ using namespace framework::expressions; void customize(std::vector& workflowOptions) { std::vector options{ - {"lut-el", VariantType::Int, 1, {"LUT input for the Electron PDG code"}}, - {"lut-mu", VariantType::Int, 1, {"LUT input for the Muon PDG code"}}, + {"lut-el", VariantType::Int, 0, {"LUT input for the Electron PDG code"}}, + {"lut-mu", VariantType::Int, 0, {"LUT input for the Muon PDG code"}}, {"lut-pi", VariantType::Int, 1, {"LUT input for the Pion PDG code"}}, - {"lut-ka", VariantType::Int, 1, {"LUT input for the Kaon PDG code"}}, - {"lut-pr", VariantType::Int, 1, {"LUT input for the Proton PDG code"}}, + {"lut-ka", VariantType::Int, 0, {"LUT input for the Kaon PDG code"}}, + {"lut-pr", VariantType::Int, 0, {"LUT input for the Proton PDG code"}}, {"lut-tr", VariantType::Int, 0, {"LUT input for the Triton PDG code"}}, {"lut-de", VariantType::Int, 0, {"LUT input for the Deuteron PDG code"}}, {"lut-he", VariantType::Int, 0, {"LUT input for the Helium3 PDG code"}}}; @@ -153,6 +153,7 @@ struct Alice3LutMaker { histos.add("QA/CovMat_sigmaSnp", "sigmaSnp" + commonTitle, kTH3F, {axisPt, axisEta, axissigmaSnp}); histos.add("QA/CovMat_sigmaTgl", "sigmaTgl" + commonTitle, kTH3F, {axisPt, axisEta, axissigmaTgl}); histos.add("QA/CovMat_sigma1Pt", "sigma1Pt" + commonTitle, kTH3F, {axisPt, axisEta, axissigma1Pt}); + histos.add("QA/sigma1Pt", "sigma1Pt" + commonTitle, kTH3F, {axisPt, axisEta, axissigma1Pt}); histos.add("QA/CovMat_rhoZY", "rhoZY" + commonTitle, kTH3F, {axisPt, axisEta, axisrhoZY}); histos.add("QA/CovMat_rhoSnpY", "rhoSnpY" + commonTitle, kTH3F, {axisPt, axisEta, axisrhoSnpY}); histos.add("QA/CovMat_rhoSnpZ", "rhoSnpZ" + commonTitle, kTH3F, {axisPt, axisEta, axisrhoSnpZ}); @@ -262,6 +263,7 @@ struct Alice3LutMaker { histos.fill(HIST("QA/CovMat_sigmaSnp"), mcParticle.pt(), mcParticle.eta(), track.sigmaSnp()); histos.fill(HIST("QA/CovMat_sigmaTgl"), mcParticle.pt(), mcParticle.eta(), track.sigmaTgl()); histos.fill(HIST("QA/CovMat_sigma1Pt"), mcParticle.pt(), mcParticle.eta(), track.sigma1Pt()); + histos.fill(HIST("QA/sigma1Pt"), mcParticle.pt(), mcParticle.eta(), std::abs(track.signed1Pt()) - 1. / mcParticle.pt()); histos.fill(HIST("QA/CovMat_rhoZY"), mcParticle.pt(), mcParticle.eta(), track.rhoZY()); histos.fill(HIST("QA/CovMat_rhoSnpY"), mcParticle.pt(), mcParticle.eta(), track.rhoSnpY()); histos.fill(HIST("QA/CovMat_rhoSnpZ"), mcParticle.pt(), mcParticle.eta(), track.rhoSnpZ()); diff --git a/ALICE3/Tasks/alice3-multicharm.cxx b/ALICE3/Tasks/alice3-multicharm.cxx index 15989109919..f001cb6e08c 100644 --- a/ALICE3/Tasks/alice3-multicharm.cxx +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -255,7 +255,7 @@ struct alice3multicharm { histos.add("hBDTScoreVsXiccPt", "hBDTScoreVsXiccPt", kTH2D, {axisPt, axisBDTScore}); histos.add("h3dBDTScore", "h3dBDTScore", kTH3D, {axisPt, axisXiccMass, axisBDTScore}); for (const auto& score : bdt.requiredScores.value) { - histPath = std::format("MLQA/RequiredBDTScore_{}/", static_cast(score * 100)); + histPath = std::format("MLQA/RequiredBDTScore_{}/", static_cast(score * 10000)); histPointers.insert({histPath + "hDCAXicDaughters", histos.add((histPath + "hDCAXicDaughters").c_str(), "hDCAXicDaughters", {kTH1D, {{axisDcaDaughters}}})}); histPointers.insert({histPath + "hDCAXiccDaughters", histos.add((histPath + "hDCAXiccDaughters").c_str(), "hDCAXiccDaughters", {kTH1D, {{axisDcaDaughters}}})}); histPointers.insert({histPath + "hDCAxyXi", histos.add((histPath + "hDCAxyXi").c_str(), "hDCAxyXi", {kTH1D, {{axisDCA}}})}); @@ -329,7 +329,7 @@ struct alice3multicharm { for (const auto& requiredScore : bdt.requiredScores.value) { if (bdtScore > requiredScore) { - histPath = std::format("MLQA/RequiredBDTScore_{}/", static_cast(requiredScore * 100)); + histPath = std::format("MLQA/RequiredBDTScore_{}/", static_cast(requiredScore * 10000)); getHist(TH1, histPath + "hDCAXicDaughters")->Fill(xiccCand.xicDauDCA() * 1e+4); getHist(TH1, histPath + "hDCAXiccDaughters")->Fill(xiccCand.xiccDauDCA() * 1e+4); getHist(TH1, histPath + "hDCAxyXi")->Fill(std::fabs(xiccCand.xiDCAxy() * 1e+4)); @@ -349,13 +349,13 @@ struct alice3multicharm { getHist(TH1, histPath + "hPi2cDCAz")->Fill(xiccCand.pi2cDCAz() * 1e+4); getHist(TH1, histPath + "hPiccDCAxy")->Fill(xiccCand.piccDCAxy() * 1e+4); getHist(TH1, histPath + "hPiccDCAz")->Fill(xiccCand.piccDCAz() * 1e+4); - getHist(TH1, histPath + "hPi1cDCAz")->Fill(xiccCand.pi1cPt()); - getHist(TH1, histPath + "hPi2cDCAz")->Fill(xiccCand.pi2cPt()); - getHist(TH1, histPath + "hPiccDCAz")->Fill(xiccCand.piccPt()); + getHist(TH1, histPath + "hPi1cPt")->Fill(xiccCand.pi1cPt()); + getHist(TH1, histPath + "hPi2cPt")->Fill(xiccCand.pi2cPt()); + getHist(TH1, histPath + "hPiccPt")->Fill(xiccCand.piccPt()); getHist(TH1, histPath + "hXiccMass")->Fill(xiccCand.xiccMass()); getHist(TH1, histPath + "hXicMass")->Fill(xiccCand.xicMass()); - getHist(TH1, histPath + "hXiccPt")->Fill(xiccCand.xiccPt()); getHist(TH1, histPath + "hXicPt")->Fill(xiccCand.xicPt()); + getHist(TH1, histPath + "hXiccPt")->Fill(xiccCand.xiccPt()); getHist(TH3, histPath + "h3dXicc")->Fill(xiccCand.xiccPt(), xiccCand.xiccEta(), xiccCand.xiccMass()); } } diff --git a/CODEOWNERS b/CODEOWNERS index 57766839579..5ad68945cbe 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -29,40 +29,41 @@ /EventFiltering/PWGCF @alibuild @lauraser @mpuccio @lietava /EventFiltering/PWGMM @alibuild @aortizve @mpuccio @lietava /EventFiltering/PWGJE @alibuild @fkrizek @nzardosh @mpuccio @lietava -/PWGCF @alibuild @saganatt @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane -/PWGCF/Core @alibuild @jgrosseo @saganatt @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane -/PWGCF/DataModel @alibuild @jgrosseo @saganatt @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane -/PWGCF/TableProducer @alibuild @jgrosseo @saganatt @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane -/PWGCF/Tasks @alibuild @jgrosseo @saganatt @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane -/PWGDQ @alibuild @iarsene @mcoquet642 @lucamicheletti93 + +/PWGCF @alibuild @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane +/PWGCF/Core @alibuild @jgrosseo @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane +/PWGCF/DataModel @alibuild @jgrosseo @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane +/PWGCF/TableProducer @alibuild @jgrosseo @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane +/PWGCF/Tasks @alibuild @jgrosseo @victor-gonzalez @zchochul @lgraczykCern @prchakra @lauraser @ariedel-cern @EmilGorm @otonvd @shouqiye @glromane +/PWGDQ @alibuild @iarsene @mcoquet642 @lucamicheletti93 @XiaozhiBai /PWGEM @alibuild @feisenhu @dsekihat @ivorobye /PWGEM/Dilepton @alibuild @mikesas @rbailhac @dsekihat @ivorobye @feisenhu @hscheid /PWGEM/PhotonMeson @alibuild @mikesas @rbailhac @m-c-danisch @novitzky @mhemmer-cern @dsekihat -/PWGHF @alibuild @vkucera @fcolamar @fgrosa @fcatalan92 @mfaggin @mmazzilli @deepathoms @NicoleBastid @hahassan7 @jpxrk @apalasciano @zhangbiao-phy @gluparel +/PWGHF @alibuild @vkucera @fcolamar @fgrosa @fcatalan92 @mfaggin @mmazzilli @deepathoms @NicoleBastid @hahassan7 @jpxrk @apalasciano @zhangbiao-phy @gluparel @stefanopolitano # PWG-LF -/PWGLF @alibuild @sustripathy @skundu692 -/PWGLF/DataModel @alibuild @sustripathy @skundu692 @gbencedi @abmodak @fmazzasc @maciacco @dmallick2 @smaff92 @ercolessi @romainschotter -/PWGLF/Tasks/GlobalEventProperties @alibuild @sustripathy @skundu692 @gbencedi @abmodak @omvazque -/PWGLF/TableProducer/GlobalEventProperties @alibuild @sustripathy @skundu692 @gbencedi @abmodak @omvazque -/PWGLF/Tasks/Nuspex @alibuild @sustripathy @skundu692 @fmazzasc @maciacco -/PWGLF/TableProducer/Nuspex @alibuild @sustripathy @skundu692 @fmazzasc @maciacco -/PWGLF/Tasks/Resonances @alibuild @sustripathy @skundu692 @dmallick2 @smaff92 -/PWGLF/TableProducer/Resonances @alibuild @sustripathy @skundu692 @dmallick2 @smaff92 -/PWGLF/Tasks/Strangeness @alibuild @sustripathy @skundu692 @ercolessi @romainschotter -/PWGLF/TableProducer/Strangeness @alibuild @sustripathy @skundu692 @ercolessi @romainschotter -/PWGLF/Utils @alibuild @sustripathy @skundu692 @gbencedi @abmodak @fmazzasc @maciacco @dmallick2 @smaff92 @ercolessi @romainschotter +/PWGLF @alibuild @sustripathy @skundu692 @mpuccio +/PWGLF/DataModel @alibuild @sustripathy @skundu692 @mpuccio @gbencedi @abmodak @fmazzasc @maciacco @dmallick2 @smaff92 @ercolessi @romainschotter +/PWGLF/Tasks/GlobalEventProperties @alibuild @sustripathy @skundu692 @mpuccio @gbencedi @abmodak @omvazque +/PWGLF/TableProducer/GlobalEventProperties @alibuild @sustripathy @skundu692 @mpuccio @gbencedi @abmodak @omvazque +/PWGLF/Tasks/Nuspex @alibuild @sustripathy @skundu692 @mpuccio @fmazzasc @maciacco +/PWGLF/TableProducer/Nuspex @alibuild @sustripathy @skundu692 @mpuccio @fmazzasc @maciacco +/PWGLF/Tasks/Resonances @alibuild @sustripathy @skundu692 @mpuccio @dmallick2 @smaff92 +/PWGLF/TableProducer/Resonances @alibuild @sustripathy @skundu692 @mpuccio @dmallick2 @smaff92 +/PWGLF/Tasks/Strangeness @alibuild @sustripathy @skundu692 @mpuccio @ercolessi @romainschotter +/PWGLF/TableProducer/Strangeness @alibuild @sustripathy @mpuccio @skundu692 @ercolessi @romainschotter +/PWGLF/Utils @alibuild @sustripathy @skundu692 @mpuccio @gbencedi @abmodak @fmazzasc @maciacco @dmallick2 @smaff92 @ercolessi @romainschotter -# PWG-MM +# PWG-MM (fused with LF, LF conveners included. Directories to be merged in the future) /PWGMM @alibuild @sustripathy @skundu692 @aalkin @jgcn /PWGMM/Mult @alibuild @sustripathy @skundu692 @aalkin @aortizve @ddobrigk @gbencedi @jgcn -/PWGMM/Lumi @alibuild @aalkin @jgcn -/PWGMM/UE @alibuild @aalkin @aortizve @jgcn +/PWGMM/Lumi @alibuild @sustripathy @skundu692 @aalkin @jgcn @gbencedi @abmodak +/PWGMM/UE @alibuild @sustripathy @skundu692 @aalkin @aortizve @jgcn /PWGUD @alibuild @pbuehler @nystrand @rolavick /PWGJE @alibuild @lhavener @maoyx @nzardosh @fjonasALICE @mfasDa @mhemmer-cern /Tools/PIDML @alibuild @saganatt /Tools/ML @alibuild @fcatalan92 @fmazzasc -/Tutorials/PWGCF @alibuild @jgrosseo @saganatt @victor-gonzalez @zchochul +/Tutorials/PWGCF @alibuild @jgrosseo @victor-gonzalez @zchochul /Tutorials/PWGDQ @alibuild @iarsene @mcoquet @lucamicheletti93 /Tutorials/PWGEM @alibuild @mikesas @rbailhac @dsekihat @ivorobye @feisenhu /Tutorials/PWGHF @alibuild @vkucera @fcolamar @fgrosa @gluparel diff --git a/Common/Core/RecoDecay.h b/Common/Core/RecoDecay.h index 5b4464e112a..fcc50d23bf8 100644 --- a/Common/Core/RecoDecay.h +++ b/Common/Core/RecoDecay.h @@ -17,21 +17,20 @@ #ifndef COMMON_CORE_RECODECAY_H_ #define COMMON_CORE_RECODECAY_H_ -// C++ includes -#include // std::find -#include // std::array -#include // std::abs, std::sqrt -#include -#include // std::apply -#include // std::move -#include // std::vector - -// ROOT includes +#include + #include // for VMC Particle Production Process #include // for PDG codes -// O2 includes -#include "CommonConstants/MathConstants.h" +#include // std::find +#include // std::array +#include // std::abs, std::sqrt +#include // std::size_t +#include // intX_t +#include // std::apply +#include // std::decay_t +#include // std::move +#include // std::vector /// Base class for calculating properties of reconstructed decays /// @@ -43,11 +42,18 @@ struct RecoDecay { // mapping of charm-hadron origin type - enum OriginType { None = 0, - Prompt, - NonPrompt }; - - static constexpr int8_t StatusCodeAfterFlavourOscillation = 92; // decay products after B0(s) flavour oscillation + enum OriginType { + None = 0, + Prompt, + NonPrompt + }; + + static constexpr int8_t StatusCodeAfterFlavourOscillation{92}; // decay products after B0(s) flavour oscillation + static constexpr int PdgQuarkMax{8}; // largest quark PDG code; o2-linter: disable=pdg/explicit-code (t' does not have a named constant.) + static constexpr int PdgBosonMin{PDG_t::kGluon}; // smallest boson (gauge or H) PDG code + static constexpr int PdgBosonMax{37}; // largest boson (gauge or H) PDG code; o2-linter: disable=pdg/explicit-code (H+ does not have a named constant.) + static constexpr int PdgDivisorMeson{100}; // order of magnitude of the meson PDG codes + static constexpr int PdgDivisorBaryon{1000}; // order of magnitude of the baryon PDG codes // Auxiliary functions @@ -110,7 +116,7 @@ struct RecoDecay { /// Calculates scalar product of vectors. /// \note Promotes numbers to double to avoid precision loss in float multiplication. - /// \param N dimension + /// \tparam N dimension /// \param vec1,vec2 vectors /// \return scalar product template @@ -137,7 +143,7 @@ struct RecoDecay { } /// Calculates magnitude squared of a vector. - /// \param N dimension + /// \tparam N dimension /// \param vec vector /// \return magnitude squared template @@ -435,7 +441,7 @@ struct RecoDecay { } /// Calculates invariant mass squared from momenta and masses of several particles (prongs). - /// \param N number of prongs + /// \tparam N number of prongs /// \param arrMom array of N 3-momentum arrays /// \param arrMass array of N masses (in the same order as arrMom) /// \return invariant mass squared @@ -445,7 +451,7 @@ struct RecoDecay { std::array momTotal{0., 0., 0.}; // candidate momentum vector double energyTot{0.}; // candidate energy for (std::size_t iProng = 0; iProng < N; ++iProng) { - for (std::size_t iMom = 0; iMom < 3; ++iMom) { + for (std::size_t iMom = 0; iMom < 3; ++iMom) { // o2-linter: disable=magic-number ({x, y, z} coordinates) momTotal[iMom] += arrMom[iProng][iMom]; } // loop over momentum components energyTot += e(arrMom[iProng], arrMass[iProng]); @@ -535,6 +541,7 @@ struct RecoDecay { } /// Finds the mother of an MC particle by looking for the expected PDG code in the mother chain. + /// \tparam acceptFlavourOscillation switch to accept decays where the mother oscillated (e.g. B0 -> B0bar) /// \param particlesMC table with MC particles /// \param particle MC particle /// \param pdgMother expected mother PDG code @@ -613,7 +620,7 @@ struct RecoDecay { } /// Gets the complete list of indices of final-state daughters of an MC particle. - /// \param checkProcess switch to accept only decay daughters by checking the production process of MC particles + /// \tparam checkProcess switch to accept only decay daughters by checking the production process of MC particles /// \param particle MC particle /// \param list vector where the indices of final-state daughters will be added /// \param arrPdgFinal array of PDG codes of particles to be considered final if found @@ -686,7 +693,7 @@ struct RecoDecay { } /// Checks whether the reconstructed decay candidate is the expected decay. - /// \tparam acceptFlavourOscillation switch to accept flavour oscillastion (i.e. B0 -> B0bar -> D+pi-) + /// \tparam acceptFlavourOscillation switch to accept decays where the mother oscillated (e.g. B0 -> B0bar) /// \tparam checkProcess switch to accept only decay daughters by checking the production process of MC particles /// \tparam acceptIncompleteReco switch to accept candidates with only part of the daughters reconstructed /// \tparam acceptTrackDecay switch to accept candidates with daughter tracks of pions and kaons which decayed @@ -750,11 +757,11 @@ struct RecoDecay { auto motherI = particleI.template mothers_first_as(); auto pdgI = std::abs(particleI.pdgCode()); auto pdgMotherI = std::abs(motherI.pdgCode()); - if (pdgI == kMuonMinus && pdgMotherI == kPiPlus) { + if (pdgI == PDG_t::kMuonMinus && pdgMotherI == PDG_t::kPiPlus) { // π → μ nPiToMuLocal++; particleI = motherI; - } else if (pdgI == kPiPlus && pdgMotherI == kKPlus) { + } else if (pdgI == PDG_t::kPiPlus && pdgMotherI == PDG_t::kKPlus) { // K → π nKaToPiLocal++; particleI = motherI; @@ -871,7 +878,8 @@ struct RecoDecay { } /// Checks whether the MC particle is the expected one. - /// \param checkProcess switch to accept only decay daughters by checking the production process of MC particles + /// \tparam acceptFlavourOscillation switch to accept decays where the mother oscillated (e.g. B0 -> B0bar) + /// \tparam checkProcess switch to accept only decay daughters by checking the production process of MC particles /// \param particlesMC table with MC particles /// \param candidate candidate MC particle /// \param pdgParticle expected particle PDG code @@ -890,7 +898,8 @@ struct RecoDecay { } /// Check whether the MC particle is the expected one and whether it decayed via the expected decay channel. - /// \param checkProcess switch to accept only decay daughters by checking the production process of MC particles + /// \tparam acceptFlavourOscillation switch to accept decays where the mother oscillated (e.g. B0 -> B0bar) + /// \tparam checkProcess switch to accept only decay daughters by checking the production process of MC particles /// \param particlesMC table with MC particles /// \param candidate candidate MC particle /// \param pdgParticle expected particle PDG code @@ -1014,7 +1023,7 @@ struct RecoDecay { arrayIds.push_back(initVec); // the first vector contains the index of the original particle auto pdgParticle = std::abs(particle.pdgCode()); bool couldBePrompt = false; - if (pdgParticle / 100 == kCharm || pdgParticle / 1000 == kCharm) { + if (pdgParticle / PdgDivisorMeson == PDG_t::kCharm || pdgParticle / PdgDivisorBaryon == PDG_t::kCharm) { couldBePrompt = true; } while (arrayIds[-stage].size() > 0) { @@ -1024,11 +1033,11 @@ struct RecoDecay { auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset()); if (particleMother.has_mothers()) { - // we exit immediately if searchUpToQuark is false and the first mother is a parton (an hadron should never be the mother of a parton) + // we exit immediately if searchUpToQuark is false and the first mother is a quark or a boson (a hadron should never be the mother of a parton) if (!searchUpToQuark) { auto mother = particlesMC.rawIteratorAt(particleMother.mothersIds().front() - particlesMC.offset()); auto pdgParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother - if (pdgParticleIMother < 9 || (pdgParticleIMother > 20 && pdgParticleIMother < 38)) { + if (pdgParticleIMother <= PdgQuarkMax || (pdgParticleIMother >= PdgBosonMin && pdgParticleIMother <= PdgBosonMax)) { return OriginType::Prompt; } } @@ -1047,22 +1056,22 @@ struct RecoDecay { if (searchUpToQuark) { if (idxBhadMothers) { - if (pdgParticleIMother / 100 == kBottom || // b mesons - pdgParticleIMother / 1000 == kBottom) // b baryons + if (pdgParticleIMother / PdgDivisorMeson == PDG_t::kBottom || // b mesons + pdgParticleIMother / PdgDivisorBaryon == PDG_t::kBottom) // b baryons { idxBhadMothers->push_back(iMother); } } - if (pdgParticleIMother == kBottom) { // b quark + if (pdgParticleIMother == PDG_t::kBottom) { // b quark return OriginType::NonPrompt; } - if (pdgParticleIMother == kCharm) { // c quark + if (pdgParticleIMother == PDG_t::kCharm) { // c quark return OriginType::Prompt; } } else { if ( - (pdgParticleIMother / 100 == kBottom || // b mesons - pdgParticleIMother / 1000 == kBottom) // b baryons + (pdgParticleIMother / PdgDivisorMeson == PDG_t::kBottom || // b mesons + pdgParticleIMother / PdgDivisorBaryon == PDG_t::kBottom) // b baryons ) { if (idxBhadMothers) { idxBhadMothers->push_back(iMother); @@ -1070,8 +1079,8 @@ struct RecoDecay { return OriginType::NonPrompt; } if ( - (pdgParticleIMother / 100 == kCharm || // c mesons - pdgParticleIMother / 1000 == kCharm) // c baryons + (pdgParticleIMother / PdgDivisorMeson == PDG_t::kCharm || // c mesons + pdgParticleIMother / PdgDivisorBaryon == PDG_t::kCharm) // c baryons ) { couldBePrompt = true; } @@ -1112,7 +1121,7 @@ struct RecoDecay { arrayIds.push_back(initVec); // the first vector contains the index of the original particle auto pdgParticle = std::abs(particle.pdgCode()); bool couldBeCharm = false; - if (pdgParticle / 100 == kCharm || pdgParticle / 1000 == kCharm) { + if (pdgParticle / PdgDivisorMeson == PDG_t::kCharm || pdgParticle / PdgDivisorBaryon == PDG_t::kCharm) { couldBeCharm = true; } while (arrayIds[-stage].size() > 0) { @@ -1122,21 +1131,21 @@ struct RecoDecay { auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset()); if (particleMother.has_mothers()) { - // we break immediately if searchUpToQuark is false and the first mother is a parton (an hadron should never be the mother of a parton) + // we break immediately if searchUpToQuark is false and the first mother is a quark or a boson (a hadron should never be the mother of a parton) if (!searchUpToQuark) { auto mother = particlesMC.rawIteratorAt(particleMother.mothersIds().front() - particlesMC.offset()); auto pdgParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother - if (pdgParticleIMother < 9 || (pdgParticleIMother > 20 && pdgParticleIMother < 38)) { + if (pdgParticleIMother <= PdgQuarkMax || (pdgParticleIMother >= PdgBosonMin && pdgParticleIMother <= PdgBosonMax)) { // auto PDGPaticle = std::abs(particleMother.pdgCode()); if ( - (pdgParticle / 100 == kBottom || // b mesons - pdgParticle / 1000 == kBottom) // b baryons + (pdgParticle / PdgDivisorMeson == PDG_t::kBottom || // b mesons + pdgParticle / PdgDivisorBaryon == PDG_t::kBottom) // b baryons ) { return OriginType::NonPrompt; // beauty } if ( - (pdgParticle / 100 == kCharm || // c mesons - pdgParticle / 1000 == kCharm) // c baryons + (pdgParticle / PdgDivisorMeson == PDG_t::kCharm || // c mesons + pdgParticle / PdgDivisorBaryon == PDG_t::kCharm) // c baryons ) { return OriginType::Prompt; // charm } @@ -1160,22 +1169,22 @@ struct RecoDecay { if (searchUpToQuark) { if (idxBhadMothers) { - if (pdgParticleIMother / 100 == kBottom || // b mesons - pdgParticleIMother / 1000 == kBottom) // b baryons + if (pdgParticleIMother / PdgDivisorMeson == PDG_t::kBottom || // b mesons + pdgParticleIMother / PdgDivisorBaryon == PDG_t::kBottom) // b baryons { idxBhadMothers->push_back(iMother); } } - if (pdgParticleIMother == kBottom) { // b quark - return OriginType::NonPrompt; // beauty + if (pdgParticleIMother == PDG_t::kBottom) { // b quark + return OriginType::NonPrompt; // beauty } - if (pdgParticleIMother == kCharm) { // c quark - return OriginType::Prompt; // charm + if (pdgParticleIMother == PDG_t::kCharm) { // c quark + return OriginType::Prompt; // charm } } else { if ( - (pdgParticleIMother / 100 == kBottom || // b mesons - pdgParticleIMother / 1000 == kBottom) // b baryons + (pdgParticleIMother / PdgDivisorMeson == PDG_t::kBottom || // b mesons + pdgParticleIMother / PdgDivisorBaryon == PDG_t::kBottom) // b baryons ) { if (idxBhadMothers) { idxBhadMothers->push_back(iMother); @@ -1183,8 +1192,8 @@ struct RecoDecay { return OriginType::NonPrompt; // beauty } if ( - (pdgParticleIMother / 100 == kCharm || // c mesons - pdgParticleIMother / 1000 == kCharm) // c baryons + (pdgParticleIMother / PdgDivisorMeson == PDG_t::kCharm || // c mesons + pdgParticleIMother / PdgDivisorBaryon == PDG_t::kCharm) // c baryons ) { couldBeCharm = true; } diff --git a/Common/Core/fwdtrackUtilities.h b/Common/Core/fwdtrackUtilities.h index 74fe125c2f0..0533bfea89c 100644 --- a/Common/Core/fwdtrackUtilities.h +++ b/Common/Core/fwdtrackUtilities.h @@ -42,6 +42,7 @@ enum class propagationPoint : int { kToRabs = 2, }; using SMatrix55 = ROOT::Math::SMatrix>; +using SMatrix55Std = ROOT::Math::SMatrix; using SMatrix5 = ROOT::Math::SVector; /// propagate fwdtrack to a certain point. @@ -98,6 +99,48 @@ o2::dataformats::GlobalFwdTrack propagateMuon(TFwdTrack const& muon, TCollision return propmuon; } + +template +o2::dataformats::GlobalFwdTrack refitGlobalMuonCov(TFwdTrack const& muon, TMFTTrack const& mft) +{ + auto muonCov = muon.getCovariances(); + auto mftCov = mft.getCovariances(); + + SMatrix55Std jacob = ROOT::Math::SMatrixIdentity(); + auto tl = muon.getTgl(); + auto invQPt = muon.getInvQPt(); + jacob(4, 3) = tl / (invQPt * std::sqrt(1 + tl * tl)); + jacob(4, 4) = -std::sqrt(1 + tl * tl) / (invQPt * invQPt); + + auto covQP = ROOT::Math::Similarity(jacob, muonCov); + mftCov(4, 0) = 0; + mftCov(4, 1) = 0; + mftCov(4, 2) = 0; + mftCov(4, 3) = 0; + + mftCov(0, 4) = 0; + mftCov(1, 4) = 0; + mftCov(2, 4) = 0; + mftCov(3, 4) = 0; + mftCov(4, 4) = covQP(4, 4); + + SMatrix55Std jacobInv = ROOT::Math::SMatrixIdentity(); + auto qp = std::sqrt(1 + tl * tl) / invQPt; + auto tlMFT = mft.getTgl(); + jacobInv(4, 3) = tlMFT / (qp * std::sqrt(1 + tlMFT * tlMFT)); + jacobInv(4, 4) = -std::sqrt(1 + tlMFT * tlMFT) / (qp * qp); + auto globalCov = ROOT::Math::Similarity(jacobInv, mftCov); + + auto invQPtGlob = std::sqrt(1 + tlMFT * tlMFT) / qp; + + o2::dataformats::GlobalFwdTrack globalTrack; + globalTrack.setParameters(mft.getParameters()); + globalTrack.setInvQPt(invQPtGlob); + globalTrack.setCovariances(globalCov); + + return globalTrack; +} + } // namespace fwdtrackutils } // namespace o2::aod diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index cdd408d4bff..b1805257bb9 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -59,11 +59,6 @@ o2physics_add_dpl_workflow(timestamp PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(timestamptester - SOURCES timestampTester.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(weak-decay-indices SOURCES weakDecayIndices.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -84,11 +79,6 @@ o2physics_add_dpl_workflow(track-dca-cov-filler-run2 PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(track-propagation-tester - SOURCES trackPropagationTester.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::trackSelectionRequest - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(calo-clusters SOURCES caloClusterProducer.cxx PUBLIC_LINK_LIBRARIES O2::DataFormatsPHOS O2::PHOSBase O2::PHOSReconstruction O2Physics::DataModel diff --git a/Common/TableProducer/PID/CMakeLists.txt b/Common/TableProducer/PID/CMakeLists.txt index 86787fd13b7..ab502d138b0 100644 --- a/Common/TableProducer/PID/CMakeLists.txt +++ b/Common/TableProducer/PID/CMakeLists.txt @@ -48,6 +48,16 @@ o2physics_add_dpl_workflow(pid-tpc-service PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(pid-tpc-service-run2 + SOURCES pidTPCServiceRun2.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::AnalysisCCDB + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(pid-tpc-service-run3 + SOURCES pidTPCServiceRun3.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::AnalysisCCDB + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(pid-tpc-base SOURCES pidTPCBase.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB diff --git a/Common/TableProducer/PID/pidTPCService.cxx b/Common/TableProducer/PID/pidTPCService.cxx index cff700fca1c..7350b9e9fa5 100644 --- a/Common/TableProducer/PID/pidTPCService.cxx +++ b/Common/TableProducer/PID/pidTPCService.cxx @@ -33,12 +33,12 @@ #include "MetadataHelper.h" #include "TableHelper.h" #include "pidTPCBase.h" -#include "pidTPCModule.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" +#include "Common/Tools/PID/pidTPCModule.h" #include "Tools/ML/model.h" #include "CCDB/BasicCCDBManager.h" @@ -98,9 +98,15 @@ struct pidTpcService { pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); } + void processTracksMCIU(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const&) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + PROCESS_SWITCH(pidTpcService, processTracks, "Process Tracks", false); PROCESS_SWITCH(pidTpcService, processTracksMC, "Process Tracks in MC (enables tune-on-data)", false); - PROCESS_SWITCH(pidTpcService, processTracksIU, "Process TracksIU (experimental)", true); + PROCESS_SWITCH(pidTpcService, processTracksIU, "Process TracksIU (Run 3)", true); + PROCESS_SWITCH(pidTpcService, processTracksMCIU, "Process TracksIUMC (Run 3)", false); }; //**************************************************************************************** diff --git a/Common/TableProducer/PID/pidTPCServiceRun2.cxx b/Common/TableProducer/PID/pidTPCServiceRun2.cxx new file mode 100644 index 00000000000..e13908cd715 --- /dev/null +++ b/Common/TableProducer/PID/pidTPCServiceRun2.cxx @@ -0,0 +1,112 @@ +// 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 trackPropagationTester.cxx +/// \brief testing ground for track propagation +/// \author ALICE + +//=============================================================== +// +// Modularized version of TPC PID task +// +//=============================================================== + +#include +#include +#include +#include +#include +// ROOT includes +#include "TFile.h" +#include "TRandom.h" +#include "TSystem.h" + +// O2 includes +#include "MetadataHelper.h" +#include "TableHelper.h" +#include "pidTPCBase.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/Tools/PID/pidTPCModule.h" +#include "Tools/ML/model.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; + +o2::common::core::MetadataHelper metadataInfo; // Metadata helper + +struct pidTpcServiceRun2 { + + // CCDB boilerplate declarations + o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + + o2::aod::pid::pidTPCProducts products; + o2::aod::pid::pidTPCConfigurables pidTPCopts; + o2::aod::pid::pidTPCModule pidTPC; + + void init(o2::framework::InitContext& initContext) + { + // CCDB boilerplate init + ccdb->setURL(ccdburl.value); + ccdb->setFatalWhenNull(false); // manual fallback in case ccdb entry empty + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdburl.value); + + // task-specific + pidTPC.init(ccdb, ccdbApi, initContext, pidTPCopts, metadataInfo); + } + + void processTracks(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + void processTracksWithTracksQA(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs, aod::TracksQA const& tracksQA) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, tracksQA, products); + } + + void processTracksMC(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const&) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + + PROCESS_SWITCH(pidTpcServiceRun2, processTracks, "Process Tracks", true); + PROCESS_SWITCH(pidTpcServiceRun2, processTracksMC, "Process Tracks in MC (enables tune-on-data)", false); +}; + +//**************************************************************************************** +/** + * Workflow definition. + */ +//**************************************************************************************** +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + // Parse the metadata for later too + metadataInfo.initMetadata(cfgc); + + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/Common/TableProducer/PID/pidTPCServiceRun3.cxx b/Common/TableProducer/PID/pidTPCServiceRun3.cxx new file mode 100644 index 00000000000..1415ecee6bf --- /dev/null +++ b/Common/TableProducer/PID/pidTPCServiceRun3.cxx @@ -0,0 +1,108 @@ +// 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 trackPropagationTester.cxx +/// \brief testing ground for track propagation +/// \author ALICE + +//=============================================================== +// +// Modularized version of TPC PID task +// +//=============================================================== + +#include +#include +#include +#include +#include +// ROOT includes +#include "TFile.h" +#include "TRandom.h" +#include "TSystem.h" + +// O2 includes +#include "MetadataHelper.h" +#include "TableHelper.h" +#include "pidTPCBase.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/Tools/PID/pidTPCModule.h" +#include "Tools/ML/model.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; + +o2::common::core::MetadataHelper metadataInfo; // Metadata helper + +struct pidTpcServiceRun3 { + + // CCDB boilerplate declarations + o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + + o2::aod::pid::pidTPCProducts products; + o2::aod::pid::pidTPCConfigurables pidTPCopts; + o2::aod::pid::pidTPCModule pidTPC; + + void init(o2::framework::InitContext& initContext) + { + // CCDB boilerplate init + ccdb->setURL(ccdburl.value); + ccdb->setFatalWhenNull(false); // manual fallback in case ccdb entry empty + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdburl.value); + + // task-specific + pidTPC.init(ccdb, ccdbApi, initContext, pidTPCopts, metadataInfo); + } + + void processTracksIU(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + + void processTracksMCIU(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const&) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + + PROCESS_SWITCH(pidTpcServiceRun3, processTracksIU, "Process TracksIU (Run 3)", true); + PROCESS_SWITCH(pidTpcServiceRun3, processTracksMCIU, "Process TracksIUMC (Run 3)", false); +}; + +//**************************************************************************************** +/** + * Workflow definition. + */ +//**************************************************************************************** +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + // Parse the metadata for later too + metadataInfo.initMetadata(cfgc); + + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index 25225144ab5..ee78a9d6f03 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -289,6 +289,8 @@ struct BcSelectionTask { bcSOR = runInfo.orbitSOR * nBCsPerOrbit; // duration of TF in bcs nBCsPerTF = confNumberOfOrbitsPerTF < 0 ? runInfo.orbitsPerTF * nBCsPerOrbit : confNumberOfOrbitsPerTF * nBCsPerOrbit; + if (strLPMProductionTag == "LHC25f3") // temporary workaround for MC production LHC25f3 anchored to Pb-Pb 2023 apass5 (to be removed once the info is in ccdb) + nBCsPerTF = 8 * nBCsPerOrbit; } // timestamp of the middle of the run used to access run-wise CCDB entries diff --git a/Common/TableProducer/eventSelectionService.cxx b/Common/TableProducer/eventSelectionService.cxx index fd713773c86..58d529e5df4 100644 --- a/Common/TableProducer/eventSelectionService.cxx +++ b/Common/TableProducer/eventSelectionService.cxx @@ -23,7 +23,7 @@ #include "Common/Core/trackUtilities.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Tools/EventSelectionTools.h" +#include "Common/Tools/EventSelectionModule.h" #include "Common/Tools/timestampModule.h" #include "CCDB/BasicCCDBManager.h" diff --git a/Common/TableProducer/multCentTable.cxx b/Common/TableProducer/multCentTable.cxx index 5b0e2c16d55..1bbf3dcd48d 100644 --- a/Common/TableProducer/multCentTable.cxx +++ b/Common/TableProducer/multCentTable.cxx @@ -20,27 +20,29 @@ // //=============================================================== -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "MetadataHelper.h" + #include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/DCA.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "CommonUtils/NameConf.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Tools/Multiplicity/MultModule.h" +#include "Common/Tools/StandardCCDBLoader.h" +#include "Common/Tools/TrackPropagationModule.h" + +#include "CCDB/BasicCCDBManager.h" #include "CCDB/CcdbApi.h" +#include "CommonConstants/GeomConstants.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsCalibration/MeanVertexObject.h" #include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "CommonConstants/GeomConstants.h" -#include "Common/Tools/TrackPropagationModule.h" -#include "Common/Tools/StandardCCDBLoader.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "MetadataHelper.h" -#include "Common/Tools/MultModule.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/DCA.h" using namespace o2; using namespace o2::framework; diff --git a/Common/TableProducer/timestampTester.cxx b/Common/TableProducer/timestampTester.cxx deleted file mode 100644 index 037cd4e38f3..00000000000 --- a/Common/TableProducer/timestampTester.cxx +++ /dev/null @@ -1,72 +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 timestamp.cxx -/// \author Nicolò Jacazio -/// \since 2020-06-22 -/// \brief A task to fill the timestamp table from run number. -/// Uses headers from CCDB -/// -#include "MetadataHelper.h" - -#include "Common/Tools/timestampModule.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonDataFormat/InteractionRecord.h" -#include "DetectorsRaw/HBFUtils.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include -#include - -using namespace o2::framework; -using namespace o2::header; -using namespace o2; - -o2::common::core::MetadataHelper metadataInfo; // Metadata helper - -struct TimestampTask { - Produces timestampTable; /// Table with SOR timestamps produced by the task - Service ccdb; /// CCDB manager to access orbit-reset timestamp - o2::ccdb::CcdbApi ccdb_api; /// API to access CCDB headers - - Configurable ccdb_url{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB database"}; - - o2::common::timestamp::timestampConfigurables timestampConfigurables; - o2::common::timestamp::TimestampModule timestampMod; - - std::vector timestampBuffer; - - void init(o2::framework::InitContext&) - { - // CCDB initialization - ccdb->setURL(ccdb_url.value); - ccdb_api.init(ccdb_url.value); - - // timestamp configuration + init - timestampMod.init(timestampConfigurables, metadataInfo); - } - - void process(aod::BCs const& bcs) - { - timestampMod.process(bcs, ccdb, timestampBuffer, timestampTable); - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - // Parse the metadata - metadataInfo.initMetadata(cfgc); - - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/Common/TableProducer/trackPropagationTester.cxx b/Common/TableProducer/trackPropagationTester.cxx deleted file mode 100644 index 18543ee0994..00000000000 --- a/Common/TableProducer/trackPropagationTester.cxx +++ /dev/null @@ -1,115 +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 trackPropagationTester.cxx -/// \brief testing ground for track propagation -/// \author ALICE - -//=============================================================== -// -// Experimental version of the track propagation task -// this utilizes an analysis task module that can be employed elsewhere -// and allows for the re-utilization of a material LUT -// -// candidate approach for core service approach -// -//=============================================================== - -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Tools/StandardCCDBLoader.h" -#include "Common/Tools/TrackPropagationModule.h" -#include "Common/Tools/TrackTuner.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "CommonConstants/GeomConstants.h" -#include "CommonUtils/NameConf.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/DCA.h" - -#include - -// The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the innermost (or second innermost) -// ITS layer. For a track without ITS, this is the TPC inner wall or for loopers in the TPC even a radius beyond that. -// In order to use the track parameters, the tracks have to be propagated to the collision vertex which is done by this task. -// The task consumes the TracksIU and TracksCovIU tables and produces Tracks and TracksCov to which then the user analysis can subscribe. -// -// This task is not needed for Run 2 converted data. -// There are two versions of the task (see process flags), one producing also the covariance matrix and the other only the tracks table. - -using namespace o2; -using namespace o2::framework; -// using namespace o2::framework::expressions; - -struct TrackPropagationTester { - o2::common::StandardCCDBLoaderConfigurables standardCCDBLoaderConfigurables; - o2::common::TrackPropagationProducts trackPropagationProducts; - o2::common::TrackPropagationConfigurables trackPropagationConfigurables; - - // the track tuner object -> needs to be here as it inherits from ConfigurableGroup (+ has its own copy of ccdbApi) - TrackTuner trackTunerObj; - - // CCDB boilerplate declarations - o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Service ccdb; - - o2::common::StandardCCDBLoader ccdbLoader; - o2::common::TrackPropagationModule trackPropagation; - - HistogramRegistry registry{"registry"}; - - void init(o2::framework::InitContext& initContext) - { - // CCDB boilerplate init - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setURL(ccdburl.value); - - // task-specific - trackPropagation.init(trackPropagationConfigurables, trackTunerObj, registry, initContext); - } - - void processReal(aod::Collisions const& collisions, soa::Join const& tracks, aod::Collisions const&, aod::BCs const& bcs) - { - // task-specific - ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); - trackPropagation.fillTrackTables(trackPropagationConfigurables, trackTunerObj, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); - } - PROCESS_SWITCH(TrackPropagationTester, processReal, "Process Real Data", true); - - // ----------------------- - void processMc(aod::Collisions const& collisions, soa::Join const& tracks, aod::McParticles const&, aod::Collisions const&, aod::BCs const& bcs) - { - ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); - trackPropagation.fillTrackTables(trackPropagationConfigurables, trackTunerObj, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); - } - PROCESS_SWITCH(TrackPropagationTester, processMc, "Process Monte Carlo", false); -}; - -//**************************************************************************************** -/** - * Workflow definition. - */ -//**************************************************************************************** -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} diff --git a/Common/Tasks/centralityStudy.cxx b/Common/Tasks/centralityStudy.cxx index a8cdea5ac09..46166ddc0d7 100644 --- a/Common/Tasks/centralityStudy.cxx +++ b/Common/Tasks/centralityStudy.cxx @@ -132,6 +132,7 @@ struct centralityStudy { ConfigurableAxis axisMultPVContributors{"axisMultPVContributors", {200, 0, 6000}, "Number of PV Contributors"}; ConfigurableAxis axisMultGlobalTracks{"axisMultGlobalTracks", {500, 0, 5000}, "Number of global tracks"}; ConfigurableAxis axisMultMFTTracks{"axisMultMFTTracks", {500, 0, 5000}, "Number of MFT tracks"}; + ConfigurableAxis axisMultMCCounts{"axisMultMCCounts", {1000, 0, 5000}, "N_{ch}"}; ConfigurableAxis axisTrackOccupancy{"axisTrackOccupancy", {50, 0, 5000}, "Track occupancy"}; ConfigurableAxis axisFT0COccupancy{"axisFT0COccupancy", {50, 0, 80000}, "FT0C occupancy"}; @@ -149,6 +150,7 @@ struct centralityStudy { // For centrality studies if requested ConfigurableAxis axisCentrality{"axisCentrality", {100, 0, 100}, "FT0C percentile"}; + ConfigurableAxis axisImpactParameter{"axisImpactParameter", {200, 0.0f, 20.0f}, "b (fm)"}; ConfigurableAxis axisPVChi2{"axisPVChi2", {300, 0, 30}, "FT0C percentile"}; ConfigurableAxis axisDeltaTime{"axisDeltaTime", {300, 0, 300}, "#Delta time"}; @@ -240,6 +242,22 @@ struct centralityStudy { histos.add("hNGlobalTracksVsNTPV", "hNGlobalTracksVsNTPV", kTH2F, {axisMultPVContributors, axisMultGlobalTracks}); } + if (doprocessCollisionsWithResolutionStudy) { + // histograms with detector signals + histos.add("hImpactParameterVsFT0A", "hImpactParameterVsFT0A", kTH2F, {axisMultFT0A, axisImpactParameter}); + histos.add("hImpactParameterVsFT0C", "hImpactParameterVsFT0C", kTH2F, {axisMultFT0C, axisImpactParameter}); + histos.add("hImpactParameterVsFT0M", "hImpactParameterVsFT0M", kTH2F, {axisMultFT0M, axisImpactParameter}); + histos.add("hImpactParameterVsFV0A", "hImpactParameterVsFV0A", kTH2F, {axisMultFV0A, axisImpactParameter}); + histos.add("hImpactParameterVsNMFTTracks", "hImpactParameterVsNMFTTracks", kTH2F, {axisMultMFTTracks, axisImpactParameter}); + histos.add("hImpactParameterVsNTPV", "hImpactParameterVsNTPV", kTH2F, {axisMultPVContributors, axisImpactParameter}); + + // histograms with actual MC counts in each region + histos.add("hImpactParameterVsMCFT0A", "hImpactParameterVsMCFT0A", kTH2F, {axisMultMCCounts, axisImpactParameter}); + histos.add("hImpactParameterVsMCFT0C", "hImpactParameterVsMCFT0C", kTH2F, {axisMultMCCounts, axisImpactParameter}); + histos.add("hImpactParameterVsMCFT0M", "hImpactParameterVsMCFT0M", kTH2F, {axisMultMCCounts, axisImpactParameter}); + histos.add("hImpactParameterVsMCFV0A", "hImpactParameterVsMCFV0A", kTH2F, {axisMultMCCounts, axisImpactParameter}); + } + if (doOccupancyStudyVsRawValues2d) { histos.add("hNcontribsProfileVsTrackOccupancyVsFT0C", "hNcontribsProfileVsTrackOccupancyVsFT0C", kTProfile2D, {axisTrackOccupancy, axisMultFT0C}); histos.add("hNGlobalTracksProfileVsTrackOccupancyVsFT0C", "hNGlobalTracksProfileVsTrackOccupancyVsFT0C", kTProfile2D, {axisTrackOccupancy, axisMultFT0C}); @@ -676,6 +694,24 @@ struct centralityStudy { getHist(TH2, histPath + "hNGlobalTracksVsNTPV")->Fill(multNTracksPV, multNTracksGlobal); } + if constexpr (requires { collision.multMCExtraId(); }) { + // requires monte carlo information + if (collision.multMCExtraId() > -1) { + auto mcCollision = collision.template multMCExtra_as>(); + histos.fill(HIST("hImpactParameterVsFT0A"), multFT0A, mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsFT0C"), multFT0C, mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsFT0M"), (multFT0A + multFT0C), mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsFV0A"), multFV0A, mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsNMFTTracks"), mftNtracks, mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsNTPV"), multNTracksPV, mcCollision.impactParameter()); + + histos.fill(HIST("hImpactParameterVsMCFT0A"), mcCollision.multMCFT0A(), mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsMCFT0C"), mcCollision.multMCFT0C(), mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsMCFT0M"), (mcCollision.multMCFT0A() + mcCollision.multMCFT0C()), mcCollision.impactParameter()); + histos.fill(HIST("hImpactParameterVsMCFV0A"), mcCollision.multMCFV0A(), mcCollision.impactParameter()); + } + } + // if the table has centrality information if constexpr (requires { collision.centFT0C(); }) { // process FT0C centrality plots @@ -709,29 +745,31 @@ struct centralityStudy { } } - if (doTimeStudies && collision.has_multBC()) { - initRun(collision); - auto multbc = collision.template multBC_as(); - uint64_t bcTimestamp = multbc.timestamp(); - float hoursAfterStartOfRun = static_cast(bcTimestamp - startOfRunTimestamp) / 3600000.0; - - getHist(TH2, histPath + "hFT0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0A()); - getHist(TH2, histPath + "hFT0CVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0C()); - getHist(TH2, histPath + "hFT0MVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0M()); - getHist(TH2, histPath + "hFV0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFV0A()); - getHist(TH2, histPath + "hFV0AOuterVsTime")->Fill(hoursAfterStartOfRun, collision.multFV0AOuter()); - getHist(TH2, histPath + "hMFTTracksVsTime")->Fill(hoursAfterStartOfRun, collision.mftNtracks()); - getHist(TH2, histPath + "hNGlobalVsTime")->Fill(hoursAfterStartOfRun, collision.multNTracksGlobal()); - getHist(TH2, histPath + "hNTPVContributorsVsTime")->Fill(hoursAfterStartOfRun, collision.multPVTotalContributors()); - getHist(TProfile, histPath + "hPVzProfileCoVsTime")->Fill(hoursAfterStartOfRun, collision.multPVz()); - getHist(TProfile, histPath + "hPVzProfileBcVsTime")->Fill(hoursAfterStartOfRun, multbc.multFT0PosZ()); - if (doTimeStudyFV0AOuterVsFT0A3d) { - histos.fill(HIST("h3dFV0AVsTime"), hoursAfterStartOfRun, collision.multFV0A(), collision.multFV0AOuter()); - } - - if (irDoRateVsTime) { - float interactionRate = mRateFetcher.fetch(ccdb.service, bcTimestamp, mRunNumber, irSource.value, irCrashOnNull) / 1000.; // kHz - getHist(TProfile, histPath + "hIRProfileVsTime")->Fill(hoursAfterStartOfRun, interactionRate); + if constexpr (requires { collision.has_multBC(); }) { + if (doTimeStudies && collision.has_multBC()) { + initRun(collision); + auto multbc = collision.template multBC_as(); + uint64_t bcTimestamp = multbc.timestamp(); + float hoursAfterStartOfRun = static_cast(bcTimestamp - startOfRunTimestamp) / 3600000.0; + + getHist(TH2, histPath + "hFT0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0A()); + getHist(TH2, histPath + "hFT0CVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0C()); + getHist(TH2, histPath + "hFT0MVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0M()); + getHist(TH2, histPath + "hFV0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFV0A()); + getHist(TH2, histPath + "hFV0AOuterVsTime")->Fill(hoursAfterStartOfRun, collision.multFV0AOuter()); + getHist(TH2, histPath + "hMFTTracksVsTime")->Fill(hoursAfterStartOfRun, collision.mftNtracks()); + getHist(TH2, histPath + "hNGlobalVsTime")->Fill(hoursAfterStartOfRun, collision.multNTracksGlobal()); + getHist(TH2, histPath + "hNTPVContributorsVsTime")->Fill(hoursAfterStartOfRun, collision.multPVTotalContributors()); + getHist(TProfile, histPath + "hPVzProfileCoVsTime")->Fill(hoursAfterStartOfRun, collision.multPVz()); + getHist(TProfile, histPath + "hPVzProfileBcVsTime")->Fill(hoursAfterStartOfRun, multbc.multFT0PosZ()); + if (doTimeStudyFV0AOuterVsFT0A3d) { + histos.fill(HIST("h3dFV0AVsTime"), hoursAfterStartOfRun, collision.multFV0A(), collision.multFV0AOuter()); + } + + if (irDoRateVsTime) { + float interactionRate = mRateFetcher.fetch(ccdb.service, bcTimestamp, mRunNumber, irSource.value, irCrashOnNull) / 1000.; // kHz + getHist(TProfile, histPath + "hIRProfileVsTime")->Fill(hoursAfterStartOfRun, interactionRate); + } } } } @@ -741,12 +779,17 @@ struct centralityStudy { genericProcessCollision(collision); } + void processCollisionsWithResolutionStudy(soa::Join::iterator const& collision, soa::Join const&) + { + genericProcessCollision(collision); + } + void processCollisionsWithCentrality(soa::Join::iterator const& collision, aod::MultBCs const&) { genericProcessCollision(collision); } - void processCollisionsWithCentralityWithNeighbours(soa::Join::iterator const& collision, aod::MultBCs const&) + void processCollisionsWithCentralityWithNeighbours(soa::Join::iterator const& collision) { genericProcessCollision(collision); } @@ -814,6 +857,7 @@ struct centralityStudy { } PROCESS_SWITCH(centralityStudy, processCollisions, "per-collision analysis", false); + PROCESS_SWITCH(centralityStudy, processCollisionsWithResolutionStudy, "per-collision analysis, with reso study", false); PROCESS_SWITCH(centralityStudy, processCollisionsWithCentrality, "per-collision analysis", true); PROCESS_SWITCH(centralityStudy, processCollisionsWithCentralityWithNeighbours, "per-collision analysis", false); PROCESS_SWITCH(centralityStudy, processBCs, "per-BC analysis", true); diff --git a/Common/Tools/EventSelectionTools.h b/Common/Tools/EventSelectionModule.h similarity index 99% rename from Common/Tools/EventSelectionTools.h rename to Common/Tools/EventSelectionModule.h index a798e1b7142..741eb60b51e 100644 --- a/Common/Tools/EventSelectionTools.h +++ b/Common/Tools/EventSelectionModule.h @@ -220,6 +220,8 @@ class BcSelectionModule bcSOR = runInfo.orbitSOR * nBCsPerOrbit; // duration of TF in bcs nBCsPerTF = bcselOpts.confNumberOfOrbitsPerTF < 0 ? runInfo.orbitsPerTF * nBCsPerOrbit : bcselOpts.confNumberOfOrbitsPerTF * nBCsPerOrbit; + if (strLPMProductionTag == "LHC25f3") // temporary workaround for MC production LHC25f3 anchored to Pb-Pb 2023 apass5 (to be removed once the info is in ccdb) + nBCsPerTF = 8 * nBCsPerOrbit; } // timestamp of the middle of the run used to access run-wise CCDB entries diff --git a/Common/Tools/MultModule.h b/Common/Tools/Multiplicity/MultModule.h similarity index 99% rename from Common/Tools/MultModule.h rename to Common/Tools/Multiplicity/MultModule.h index 3623543a54d..bed8817c124 100644 --- a/Common/Tools/MultModule.h +++ b/Common/Tools/Multiplicity/MultModule.h @@ -24,6 +24,7 @@ #include "Common/DataModel/Multiplicity.h" #include +#include #include #include diff --git a/Common/Tools/Multiplicity/multCalibrator.cxx b/Common/Tools/Multiplicity/multCalibrator.cxx index 493a3d5feac..7d3f4e51019 100644 --- a/Common/Tools/Multiplicity/multCalibrator.cxx +++ b/Common/Tools/Multiplicity/multCalibrator.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/Common/TableProducer/PID/pidTPCModule.h b/Common/Tools/PID/pidTPCModule.h similarity index 99% rename from Common/TableProducer/PID/pidTPCModule.h rename to Common/Tools/PID/pidTPCModule.h index 321b6e39329..47ad5d5a01c 100644 --- a/Common/TableProducer/PID/pidTPCModule.h +++ b/Common/Tools/PID/pidTPCModule.h @@ -34,7 +34,6 @@ // O2 includes #include "MetadataHelper.h" #include "TableHelper.h" -#include "pidTPCBase.h" #include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/PID/TPCPIDResponse.h" @@ -50,6 +49,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" +#include namespace o2::aod { diff --git a/Common/Tools/TrackTuner.h b/Common/Tools/TrackTuner.h index 60cf377a410..ca7ae6c5eb5 100644 --- a/Common/Tools/TrackTuner.h +++ b/Common/Tools/TrackTuner.h @@ -39,6 +39,7 @@ #include #include +#include #include @@ -104,7 +105,6 @@ struct TrackTuner : o2::framework::ConfigurableGroup { bool isConfigFromConfigurables = false; int nPhiBins = 1; - o2::ccdb::CcdbApi ccdbApi; std::map metadata; std::vector> grDcaXYResVsPtPionMC; @@ -449,51 +449,52 @@ struct TrackTuner : o2::framework::ConfigurableGroup { void getDcaGraphs() { - std::string fullNameInputFile = ""; - std::string fullNameFileQoverPt = ""; + std::string fullNameInputFile = pathInputFile + std::string("/") + nameInputFile; + std::string fullNameFileQoverPt = pathFileQoverPt + std::string("/") + nameFileQoverPt; + TList* ccdb_object_dca = nullptr; + TList* ccdb_object_qoverpt = nullptr; + + std::string grOneOverPtPionNameMC = "sigmaVsPtMc"; + std::string grOneOverPtPionNameData = "sigmaVsPtData"; if (isInputFileFromCCDB) { /// use input correction file from CCDB - // properly init the ccdb - std::string tmpDir = "."; - ccdbApi.init("http://alice-ccdb.cern.ch"); + // get the TList from the DCA correction file present in CCDB + ccdb_object_dca = o2::ccdb::BasicCCDBManager::instance().get(pathInputFile); + LOG(info) << " [TrackTuner] ccdb_object_dca " << ccdb_object_dca; - // get the DCA correction file from CCDB - if (!ccdbApi.retrieveBlob(pathInputFile.data(), tmpDir, metadata, 0, false, nameInputFile.data())) { - LOG(fatal) << "[TrackTuner] input file for DCA corrections not found on CCDB, please check the pathInputFile and nameInputFile!"; + // get the TList from the Q/Pt correction file from CCDB + if (updateCurvature || updateCurvatureIU) { + ccdb_object_qoverpt = o2::ccdb::BasicCCDBManager::instance().get(pathFileQoverPt); + LOG(info) << " [TrackTuner] ccdb_object_qoverpt " << ccdb_object_qoverpt; } - - // get the Q/Pt correction file from CCDB - if (!ccdbApi.retrieveBlob(pathFileQoverPt.data(), tmpDir, metadata, 0, false, nameFileQoverPt.data())) { - LOG(fatal) << "[TrackTuner] input file for Q/Pt corrections not found on CCDB, please check the pathFileQoverPt and nameFileQoverPt!"; - } - // point to the file in the tmp local folder - fullNameInputFile = tmpDir + std::string("/") + nameInputFile; - fullNameFileQoverPt = tmpDir + std::string("/") + nameFileQoverPt; } else { /// use input correction file from local filesystem - fullNameInputFile = pathInputFile + std::string("/") + nameInputFile; - fullNameFileQoverPt = pathFileQoverPt + std::string("/") + nameFileQoverPt; - } - /// open the input correction file - std::unique_ptr inputFile(TFile::Open(fullNameInputFile.c_str(), "READ")); - if (!inputFile.get()) { - LOG(fatal) << "Something wrong with the input file" << fullNameInputFile << " for dca correction. Fix it!"; - } - std::unique_ptr inputFileQoverPt(TFile::Open(fullNameFileQoverPt.c_str(), "READ")); - if (!inputFileQoverPt.get() && (updateCurvature || updateCurvatureIU)) { - LOG(fatal) << "Something wrong with the Q/Pt input file" << fullNameFileQoverPt << " for Q/Pt correction. Fix it!"; + + /// open the input correction file - dca correction + TFile* inputFile = TFile::Open(fullNameInputFile.c_str(), "READ"); + if (!inputFile) { + LOG(fatal) << "[TrackTuner] Something wrong with the local input file" << fullNameInputFile << " for dca correction. Fix it!"; + } + ccdb_object_dca = dynamic_cast(inputFile->Get("ccdb_object")); + + /// open the input correction file - q/pt correction + TFile* inputFileQoverPt = TFile::Open(fullNameFileQoverPt.c_str(), "READ"); + if (!inputFileQoverPt && (updateCurvature || updateCurvatureIU)) { + LOG(fatal) << "Something wrong with the Q/Pt input file" << fullNameFileQoverPt << " for Q/Pt correction. Fix it!"; + } + ccdb_object_qoverpt = dynamic_cast(inputFileQoverPt->Get("ccdb_object")); } - // choose wheter to use corrections w/ PV refit or w/o it, and retrieve the proper TDirectory + // choose wheter to use corrections w/ PV refit or w/o it, and retrieve the proper TList std::string dir = "woPvRefit"; if (usePvRefitCorrections) { dir = "withPvRefit"; } - TDirectory* td = dynamic_cast(inputFile->Get(dir.c_str())); + TList* td = dynamic_cast(ccdb_object_dca->FindObject(dir.c_str())); if (!td) { - LOG(fatal) << "TDirectory " << td << " not found in input file" << inputFile->GetName() << ". Fix it!"; + LOG(fatal) << "[TrackTuner] TList " << td << " not found in ccdb_object_dca. Fix it!"; } int inputNphiBins = nPhiBins; @@ -522,7 +523,7 @@ struct TrackTuner : o2::framework::ConfigurableGroup { /// Lambda expression to get the TGraphErrors from file auto loadGraph = [&](int phiBin, const std::string& strBaseName) -> TGraphErrors* { std::string strGraphName = inputNphiBins != 0 ? fmt::format("{}_{}", strBaseName, phiBin) : strBaseName; - TObject* obj = td->Get(strGraphName.c_str()); + TObject* obj = td->FindObject(strGraphName.c_str()); if (!obj) { LOG(fatal) << "[TrackTuner] TGraphErrors not found in the Input Root file: " << strGraphName; td->ls(); @@ -564,12 +565,9 @@ struct TrackTuner : o2::framework::ConfigurableGroup { } } - std::string grOneOverPtPionNameMC = "sigmaVsPtMc"; - std::string grOneOverPtPionNameData = "sigmaVsPtData"; - if (updateCurvature || updateCurvatureIU) { - grOneOverPtPionMC.reset(dynamic_cast(inputFileQoverPt->Get(grOneOverPtPionNameMC.c_str()))); - grOneOverPtPionData.reset(dynamic_cast(inputFileQoverPt->Get(grOneOverPtPionNameData.c_str()))); + grOneOverPtPionMC.reset(dynamic_cast(ccdb_object_qoverpt->FindObject(grOneOverPtPionNameMC.c_str()))); + grOneOverPtPionData.reset(dynamic_cast(ccdb_object_qoverpt->FindObject(grOneOverPtPionNameData.c_str()))); } } // getDcaGraphs() ends here diff --git a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx index 7d23ded67aa..3fc293c7e84 100644 --- a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx +++ b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx @@ -15,6 +15,7 @@ /// \author Igor Altsybeev #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/Centrality.h" @@ -49,7 +50,8 @@ using FullTracksIU = soa::Join confAddBasicQAhistos{"AddBasicQAhistos", true, "0 - add basic histograms, 1 - skip"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confAddBasicQAhistos{"FlagAddBasicQAhistos", true, "0 - add basic histograms, 1 - skip"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confAddTimeDependentHistos{"FlagAddTimeDependentHistos", true, "0 - add time-dependent histograms, 1 - skip"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confTimeIntervalForOccupancyCalculation{"TimeIntervalForOccupancyCalculation", 100, "Time interval for TPC occupancy calculation, us"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confOccupancyHistCoeffNtracksForOccupancy{"HistCoeffNtracksForOccupancy", 1., "Coefficient for max nTracks in occupancy histos"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confOccupancyHistCoeffNbins2D{"HistCoeffNbins2D", 1., "Coefficient for nBins in occupancy 2D histos"}; // o2-linter: disable=name/configurable (temporary fix) @@ -63,7 +65,7 @@ struct DetectorOccupancyQaTask { Configurable confFlagUseNoHighMultCollInPrevRof{"FlagUseNoHighMultCollInPrevRof", false, "Suppress high-multiplicity prev-ROF events for occupancy historams"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confFlagCentralityIsAvailable{"FlagCentralityIsAvailable", true, "Fill centrality-related historams"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confFlagManyHeavyHistos{"FlagManyHeavyHistos", true, "Fill more TH2, TH3, THn historams"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable confFlagIsTOFIsTRDdtStudy{"FlagIsTOFIsTRDdtStudy", true, "Fill THn dt historams with isTOF and isTRD condition"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confFlagIsTOFIsTRDdtStudy{"FlagIsTOFIsTRDdtStudy", false, "Fill THn dt historams with isTOF and isTRD condition"}; // o2-linter: disable=name/configurable (temporary fix) // configuration for small time binning Configurable confTimeIntervalForSmallBins{"TimeIntervalForSmallBins", 100, "Time interval for TPC occupancy calculation in small bins, +/-, us"}; // o2-linter: disable=name/configurable (temporary fix) @@ -79,12 +81,12 @@ struct DetectorOccupancyQaTask { Configurable confCutMinTPCcls{"MinNumTPCcls", 50, "min number of TPC clusters for a current event"}; // o2-linter: disable=name/configurable (temporary fix) // config for QA histograms - Configurable confAddTracksVsFwdHistos{"AddTracksVsFwdHistos", true, "0 - add histograms, 1 - skip"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable nBinsTracks{"nBinsTracks", 400, "N bins in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable nMaxTracks{"nMaxTracks", 8000, "N max in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable nMaxGlobalTracks{"nMaxGlobalTracks", 3000, "N max in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable nBinsMultFwd{"nBinsMultFwd", 400, "N bins in mult fwd histo"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable nMaxMultFwd{"nMaxMultFwd", 200000, "N max in mult fwd histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confAddTracksVsFwdHistos{"FlagAddTracksVsFwdHistos", true, "0 - add histograms, 1 - skip"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nBinsTracks{"nBinsTracks", 400, "N bins in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nMaxTracks{"nMaxTracks", 8000, "N max in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nMaxGlobalTracks{"nMaxGlobalTracks", 3000, "N max in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nBinsMultFwd{"nBinsMultFwd", 400, "N bins in mult fwd histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nMaxMultFwd{"nMaxMultFwd", 200000, "N max in mult fwd histo"}; // o2-linter: disable=name/configurable (temporary fix) Configurable nBinsOccupancy{"nBinsOccupancy", 150, "N bins for occupancy axis"}; // o2-linter: disable=name/configurable (temporary fix) Configurable nMaxOccupancy{"nMaxOccupancy", 15000, "N for max of the occupancy axis"}; // o2-linter: disable=name/configurable (temporary fix) @@ -105,6 +107,16 @@ struct DetectorOccupancyQaTask { Configurable> confTimeSlicesForPastFutureStudies{"TimeSlicesForPastFutureStudies", {-40, -10, 20, 50, 80}, "Time slices for past/future studies, us"}; + // configuration for THnD multi-dim histo(s): + Configurable confFlagFillTHn{"FlagFillTHn", false, "Fill THn historams for multi-dim QA"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confTHnAxis_nPhiBins{"THn_nPhiBins", 180, "nPhiBins"}; // o2-linter: disable=name/configurable (temporary fix) + ConfigurableAxis confTHnAxis_R{"THn_R", {8, -0.5f, 7.5f}, "ids of radii"}; // o2-linter: disable=name/configurable (temporary fix) + ConfigurableAxis confTHnAxis_qOp{"THn_qOp", {16, -4.f, 4.f}, "qOp"}; // o2-linter: disable=name/configurable (temporary fix) + ConfigurableAxis confTHnAxis_IR{"THn_IR", {VARIABLE_WIDTH, 0, 12, 25, 38, 50}, "IR, kHz"}; // o2-linter: disable=name/configurable (temporary fix) + ConfigurableAxis confTHnAxis_occ{"THn_occupancy", {VARIABLE_WIDTH, 0, 500, 1000, 2000, 4000, 6000, 8000}, "weighted occupancy"}; // o2-linter: disable=name/configurable (temporary fix) + ConfigurableAxis confTHnAxis_centr{"THn_centr", {VARIABLE_WIDTH, 0, 500, 1000, 2000, 4000}, "centrality by nPVtracks"}; // o2-linter: disable=name/configurable (temporary fix) + ConfigurableAxis confTHnAxis_eta{"THn_eta", {8, -0.8f, 0.8f}, "eta"}; // o2-linter: disable=name/configurable (temporary fix) + uint64_t minGlobalBC = 0; Service ccdb; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -115,6 +127,7 @@ struct DetectorOccupancyQaTask { double minOrbit; int64_t bcSOR = 0; // global bc of the start of the first orbit, setting 0 by default for unanchored MC int64_t nBCsPerTF = 32 * nBCsPerOrbit; // duration of TF in bcs, should be 128*3564 or 32*3564, setting 128 orbits by default sfor unanchored MC + ctpRateFetcher mRateFetcher; // save time "slices" for several collisions for QA bool flagFillQAtimeOccupHist = false; @@ -133,12 +146,38 @@ struct DetectorOccupancyQaTask { histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vertexTOFmatched", ";bc in TF; n collisions", kTH1F, {axisBCinTF}); histos.add("hNcolVsBcInTF/hNcolVsBcInTFafterMaxBcCut", ";bc in TF; n collisions", kTH1F, {axisBCinTF}); + // QA of occupancy-based event selection + histos.add("hOccupancy", "", kTH1D, {{15002, -1.5, 15000.5}}); + + AxisSpec axisOccupancyTracks{nBinsOccupancy, 0., nMaxOccupancy, "occupancy (n ITS tracks weighted)"}; + if (confFlagCentralityIsAvailable) { + AxisSpec axisCentrality{100, 0, 100, "centrality, %"}; + histos.add("hCentrVsOccupancy", "hCentrVsOccupancy", kTH2F, {axisCentrality, axisOccupancyTracks}); + histos.add("hCentrVsOccupancyNoCollStd", "hCentrVsOccupancyNoCollStd", kTH2F, {axisCentrality, axisOccupancyTracks}); + } + // track QA counters + histos.add("nTrackCounter_after_cuts_QA", "", kTH1D, {{12, -0.5, 11.5, "track QA"}}); + TAxis* axTrackCounters = reinterpret_cast(histos.get(HIST("nTrackCounter_after_cuts_QA"))->GetXaxis()); + axTrackCounters->SetBinLabel(1, "all"); + axTrackCounters->SetBinLabel(2, "PVcontrib"); + axTrackCounters->SetBinLabel(3, "ptCut"); + axTrackCounters->SetBinLabel(4, "etaCut"); + axTrackCounters->SetBinLabel(5, "itsNCls>=5"); + axTrackCounters->SetBinLabel(6, "isGlobal,nTPCcls>=70"); + axTrackCounters->SetBinLabel(7, "passedTPCRefit"); + axTrackCounters->SetBinLabel(8, "occupancy>=0"); + axTrackCounters->SetBinLabel(9, "fracton nClsNoPID (0,0.8)"); + axTrackCounters->SetBinLabel(10, "pos"); + axTrackCounters->SetBinLabel(11, "neg"); + // histograms for occupancy-in-time-window study double kMaxOccup = confOccupancyHistCoeffNtracksForOccupancy; double kMaxThisEv = confCoeffMaxNtracksThisEvent; // 1D, dE/dx, etc. if (confAddBasicQAhistos) { + histos.add("hOccupancyVsOrbit", ";orbit id;weighted occupancy;n events", kTH2F, {{128, -0.5, 127.5}, {600, 0, 15000}}); + int nMax1D = kMaxThisEv * 8000; histos.add("hNumITS567tracksPerCollision", ";n tracks;n events", kTH1D, {{nMax1D, -0.5, nMax1D - 0.5}}); histos.add("hNumITS567tracksPerCollisionSel", ";n tracks;n events", kTH1D, {{nMax1D, -0.5, nMax1D - 0.5}}); @@ -158,21 +197,6 @@ struct DetectorOccupancyQaTask { histos.add("hNumUniqueBCInTimeWindow", ";n collisions;n events", kTH1D, {{201, -0.5, 200.5}}); - // track QA counters - histos.add("nTrackCounter_after_cuts_QA", "", kTH1D, {{12, -0.5, 11.5, "track QA"}}); - TAxis* axTrackCounters = reinterpret_cast(histos.get(HIST("nTrackCounter_after_cuts_QA"))->GetXaxis()); - axTrackCounters->SetBinLabel(1, "all"); - axTrackCounters->SetBinLabel(2, "PVcontrib"); - axTrackCounters->SetBinLabel(3, "ptCut"); - axTrackCounters->SetBinLabel(4, "etaCut"); - axTrackCounters->SetBinLabel(5, "itsNCls>=5"); - axTrackCounters->SetBinLabel(6, "isGlobal,nTPCcls>=70"); - axTrackCounters->SetBinLabel(7, "passedTPCRefit"); - axTrackCounters->SetBinLabel(8, "occupancy>=0"); - axTrackCounters->SetBinLabel(9, "fracton nClsNoPID (0,0.8)"); - axTrackCounters->SetBinLabel(10, "pos"); - axTrackCounters->SetBinLabel(11, "neg"); - // dE/dx AxisSpec axisDeDx{800, 0.0, 800.0, "dE/dx (a. u.)"}; histos.add("dEdx_vs_Momentum", "dE/dx", kTH2F, {{1000, -5.0, 5.0, "#it{p}/Z (GeV/c)"}, axisDeDx}); @@ -412,6 +436,15 @@ struct DetectorOccupancyQaTask { histos.add("hNumITSTPC_vs_FT0CthisCol_vs_FT0CamplInTimeWindow_kNoCollInTimeRangeNarrow", ";FT0C this collision;n ITS-TPC tracks, this collision;FT0C ampl. sum in time window", kTH3D, {{nBins3D, 0, kMaxThisEv * 80000}, {nBins3D, 0, kMaxThisEv * 8000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 250000}}); histos.add("hNumITS567_vs_FT0CthisCol_vs_FT0CamplInTimeWindow_kNoCollInTimeRangeNarrow", ";FT0C this collision;n ITS567cls tracks, this collision;FT0C ampl. sum in time window", kTH3D, {{nBins3D, 0, kMaxThisEv * 80000}, {nBins3D, 0, kMaxThisEv * 8000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 250000}}); } + + // THnD for Marian: + if (confFlagFillTHn) { + AxisSpec axis_THnF_phi{confTHnAxis_nPhiBins, 0, TMath::TwoPi(), ""}; // φ at radius: 360 bins + histos.add("THnD_histos/phi_R_qOp_IR_occ_centr_eta", ";phi;R;qOp;IR;occ;cent;eta", kTHnF, {axis_THnF_phi, confTHnAxis_R, confTHnAxis_qOp, confTHnAxis_IR, confTHnAxis_occ, confTHnAxis_centr, confTHnAxis_eta}); + + histos.add("THnD_histos/QA_under_asin", "", kTH1F, {{200, -4, 4}}); + histos.add("THnD_histos/QA_asin", "", kTH1F, {{200, -8, 8}}); + } // nD, time bins to cover the range -confTimeIntervalForSmallBins... +confTimeIntervalForSmallBins (us) double timeBinSize = 2 * confTimeIntervalForSmallBins / confNumberOfSmallTimeBins; std::vector arrTimeBins; @@ -420,50 +453,42 @@ struct DetectorOccupancyQaTask { const AxisSpec axisTimeBins{arrTimeBins, "#Delta t, #mus"}; int nBinsX = 20; int nBinsY = 40; - histos.add("occupancyInTimeBins", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); - histos.add("occupancyInTimeBins_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS-TPC tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); - histos.add("occupancyInTimeBins_nITS567_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS567cls tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); - if (confFlagManyHeavyHistos) { - histos.add("occupancyInTimeBins_BEFORE_sel", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); - histos.add("occupancyInTimeBins_occupByFT0_BEFORE_sel", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + if (confAddTimeDependentHistos) { + histos.add("occupancyInTimeBins", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); + histos.add("occupancyInTimeBins_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS-TPC tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); + histos.add("occupancyInTimeBins_nITS567_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS567cls tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); - histos.add("occupancyInTimeBins_occupByFT0", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); - histos.add("occupancyInTimeBins_occupByFT0_kNoCollInTimeRangeNarrow", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + if (confFlagManyHeavyHistos) { + histos.add("occupancyInTimeBins_BEFORE_sel", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); + histos.add("occupancyInTimeBins_occupByFT0_BEFORE_sel", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); - histos.add("occupancyInTimeBins_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + histos.add("occupancyInTimeBins_occupByFT0", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + histos.add("occupancyInTimeBins_occupByFT0_kNoCollInTimeRangeNarrow", ";time bin (#mus);n ITS tracks with 5,6,7 cls, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBinsX, 0, kMaxThisEv * 4000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); - histos.add("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS567cls tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); - histos.add("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow_NoCollInRofStrict", ";time bin (#mus);FT0C this collision, this collision;n ITS567cls tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); - } - if (confFlagIsTOFIsTRDdtStudy) { - histos.add("occupancyInTimeBins_nITSTOF_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITSTOF tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); - histos.add("occupancyInTimeBins_nITSTRD_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITSTRD tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); + histos.add("occupancyInTimeBins_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS-TPC tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + + histos.add("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITS567cls tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + histos.add("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow_NoCollInRofStrict", ";time bin (#mus);FT0C this collision, this collision;n ITS567cls tracks, this collision;sum FT0 in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 100000}}); + } + if (confFlagIsTOFIsTRDdtStudy) { + histos.add("occupancyInTimeBins_nITSTOF_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITSTOF tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); + histos.add("occupancyInTimeBins_nITSTRD_vs_FT0thisCol_kNoCollInTimeRangeNarrow", ";time bin (#mus);FT0C this collision, this collision;n ITSTRD tracks, this collision;ITS tracks with 5,6,7 cls in time window", kTHnF, {axisTimeBins, {nBins3D, 0, kMaxThisEv * 100000}, {nBinsY, 0, kMaxThisEv * 4000}, {nBins3DoccupancyAxis, 0, kMaxOccup * 10000}}); + } + + histos.add("qaForHighOccupITStracksInTimeBinPast", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); + histos.add("qaForHighOccupITStracksInTimeBinFuture1", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); + histos.add("qaForHighOccupITStracksInTimeBinFuture2", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); + histos.add("qaForHighOccupITStracksForNeighbourEvents", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); + + // save dt information for several first collisions for QA + histos.add("histOccupInTimeBinsQA", ";dt;this coll id", kTH2F, {axisTimeBins, {nCollisionsForTimeBinQA, -0.5, nCollisionsForTimeBinQA - 0.5}}); } histos.add("thisEventITStracksInTimeBins", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); histos.add("thisEventITSTPCtracksInTimeBins", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); histos.add("thisEventFT0CInTimeBins", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); - histos.add("qaForHighOccupITStracksInTimeBinPast", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); - histos.add("qaForHighOccupITStracksInTimeBinFuture1", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); - histos.add("qaForHighOccupITStracksInTimeBinFuture2", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); - histos.add("qaForHighOccupITStracksForNeighbourEvents", ";time bin (#mus);n tracks", kTH1F, {axisTimeBins}); - - // save dt information for several first collisions for QA - histos.add("histOccupInTimeBinsQA", ";dt;this coll id", kTH2F, {axisTimeBins, {nCollisionsForTimeBinQA, -0.5, nCollisionsForTimeBinQA - 0.5}}); - - // QA of occupancy-based event selection - histos.add("hOccupancy", "", kTH1D, {{15002, -1.5, 15000.5}}); - histos.add("hOccupancyVsOrbit", ";orbit id;weighted occupancy;n events", kTH2F, {{128, -0.5, 127.5}, {600, 0, 15000}}); - - AxisSpec axisOccupancyTracks{nBinsOccupancy, 0., nMaxOccupancy, "occupancy (n ITS tracks weighted)"}; - if (confFlagCentralityIsAvailable) { - AxisSpec axisCentrality{100, 0, 100, "centrality, %"}; - histos.add("hCentrVsOccupancy", "hCentrVsOccupancy", kTH2F, {axisCentrality, axisOccupancyTracks}); - histos.add("hCentrVsOccupancyNoCollStd", "hCentrVsOccupancyNoCollStd", kTH2F, {axisCentrality, axisOccupancyTracks}); - } - if (confAddTracksVsFwdHistos) { AxisSpec axisNtracks{nBinsTracks, -0.5, nMaxTracks - 0.5, "n tracks"}; AxisSpec axisNtracksGlobal{nBinsTracks, -0.5, nMaxGlobalTracks - 0.5, "n tracks"}; @@ -917,7 +942,7 @@ struct DetectorOccupancyQaTask { int nFT0CInTimeBin = histos.get(HIST("thisEventFT0CInTimeBins"))->GetBinContent(iT + 1); - if (confFlagManyHeavyHistos) { + if (confAddTimeDependentHistos && confFlagManyHeavyHistos) { histos.fill(HIST("occupancyInTimeBins_BEFORE_sel"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nITStrInTimeBin); histos.fill(HIST("occupancyInTimeBins_occupByFT0_BEFORE_sel"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); } @@ -927,43 +952,45 @@ struct DetectorOccupancyQaTask { if (confFlagUseNoHighMultCollInPrevRof && !col.selection_bit(kNoHighMultCollInPrevRof)) flagFillOccupVsDt = false; - if (sel && std::fabs(col.posZ()) < 10 && flagFillOccupVsDt) { - histos.fill(HIST("occupancyInTimeBins"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nITStrInTimeBin); - if (confFlagManyHeavyHistos) - histos.fill(HIST("occupancyInTimeBins_occupByFT0"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); - - if (col.selection_bit(kNoCollInTimeRangeNarrow)) { - histos.fill(HIST("occupancyInTimeBins_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nITStrInTimeBin); - histos.fill(HIST("occupancyInTimeBins_nITS567_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITS567perCollPtEtaCuts[colIndex], nITStrInTimeBin); - if (confFlagIsTOFIsTRDdtStudy) { - histos.fill(HIST("occupancyInTimeBins_nITSTOF_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITSTOFperCollPtEtaCuts[colIndex], nITStrInTimeBin); - histos.fill(HIST("occupancyInTimeBins_nITSTRD_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITSTRDperCollPtEtaCuts[colIndex], nITStrInTimeBin); - } - if (confFlagManyHeavyHistos) { - histos.fill(HIST("occupancyInTimeBins_occupByFT0_kNoCollInTimeRangeNarrow"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); - histos.fill(HIST("occupancyInTimeBins_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); + if (confAddTimeDependentHistos) { + if (sel && std::fabs(col.posZ()) < 10 && flagFillOccupVsDt) { + histos.fill(HIST("occupancyInTimeBins"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nITStrInTimeBin); + if (confFlagManyHeavyHistos) + histos.fill(HIST("occupancyInTimeBins_occupByFT0"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); + + if (col.selection_bit(kNoCollInTimeRangeNarrow)) { + histos.fill(HIST("occupancyInTimeBins_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nITStrInTimeBin); + histos.fill(HIST("occupancyInTimeBins_nITS567_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITS567perCollPtEtaCuts[colIndex], nITStrInTimeBin); + if (confFlagIsTOFIsTRDdtStudy) { + histos.fill(HIST("occupancyInTimeBins_nITSTOF_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITSTOFperCollPtEtaCuts[colIndex], nITStrInTimeBin); + histos.fill(HIST("occupancyInTimeBins_nITSTRD_vs_FT0thisCol_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITSTRDperCollPtEtaCuts[colIndex], nITStrInTimeBin); + } + if (confFlagManyHeavyHistos) { + histos.fill(HIST("occupancyInTimeBins_occupByFT0_kNoCollInTimeRangeNarrow"), dt, vTracksITS567perCollPtEtaCuts[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); + histos.fill(HIST("occupancyInTimeBins_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], confFlagUseGlobalTracks ? vTracksGlobalPerCollPtEtaCuts[colIndex] : vTracksITSTPCperCollPtEtaCuts[colIndex], nFT0CInTimeBin); - histos.fill(HIST("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITS567perCollPtEtaCuts[colIndex], nFT0CInTimeBin); - if (col.selection_bit(kNoCollInRofStrict)) - histos.fill(HIST("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow_NoCollInRofStrict"), dt, vAmpFT0CperColl[colIndex], vTracksITS567perCollPtEtaCuts[colIndex], nFT0CInTimeBin); + histos.fill(HIST("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow"), dt, vAmpFT0CperColl[colIndex], vTracksITS567perCollPtEtaCuts[colIndex], nFT0CInTimeBin); + if (col.selection_bit(kNoCollInRofStrict)) + histos.fill(HIST("occupancyInTimeBins_nITS567_vs_FT0thisCol_occupByFT0_kNoCollInTimeRangeNarrow_NoCollInRofStrict"), dt, vAmpFT0CperColl[colIndex], vTracksITS567perCollPtEtaCuts[colIndex], nFT0CInTimeBin); + } } } - } - - // - - if (counterQAtimeOccupHistos < nCollisionsForTimeBinQA) - histos.fill(HIST("histOccupInTimeBinsQA"), dt, counterQAtimeOccupHistos + 1, nITStrInTimeBin); - // QA for high occup in time bins - if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 2) - histos.fill(HIST("qaForHighOccupITStracksInTimeBinPast"), dt, nITStrInTimeBin); - if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 3) - histos.fill(HIST("qaForHighOccupITStracksInTimeBinFuture1"), dt, nITStrInTimeBin); - if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 4) - histos.fill(HIST("qaForHighOccupITStracksInTimeBinFuture2"), dt, nITStrInTimeBin); - if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 5) - histos.fill(HIST("qaForHighOccupITStracksForNeighbourEvents"), dt, nITStrInTimeBin); + // + + if (counterQAtimeOccupHistos < nCollisionsForTimeBinQA) + histos.fill(HIST("histOccupInTimeBinsQA"), dt, counterQAtimeOccupHistos + 1, nITStrInTimeBin); + + // QA for high occup in time bins + if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 2) + histos.fill(HIST("qaForHighOccupITStracksInTimeBinPast"), dt, nITStrInTimeBin); + if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 3) + histos.fill(HIST("qaForHighOccupITStracksInTimeBinFuture1"), dt, nITStrInTimeBin); + if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 4) + histos.fill(HIST("qaForHighOccupITStracksInTimeBinFuture2"), dt, nITStrInTimeBin); + if (vFlagsForEtaQAvsOccupancyInDeltaTimeWins[colIndex] == 5) + histos.fill(HIST("qaForHighOccupITStracksForNeighbourEvents"), dt, nITStrInTimeBin); + } // end of confAddTimeDependentHistos } // reset delta time hist for this event @@ -1009,6 +1036,10 @@ struct DetectorOccupancyQaTask { int occupancy = col.trackOccupancyInTimeRange(); auto tracksGrouped = tracks.sliceBy(perCollision, col.globalIndex()); + const auto& bc = col.foundBC_as(); + int64_t ts = bc.timestamp(); + double IR = mRateFetcher.fetch(ccdb.service, ts, runNumber, "ZNC hadronic") * 1.e-3; // kHz + // pre-calc nPV for (const auto& track : tracksGrouped) { if (!track.isPVContributor()) @@ -1021,7 +1052,7 @@ struct DetectorOccupancyQaTask { continue; nPV++; } - if (occupancy >= 0) { + if (occupancy >= 0 && confAddBasicQAhistos) { histos.fill(HIST("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy"), bcInTF, occupancy); if (col.selection_bit(kIsVertexTOFmatched)) histos.fill(HIST("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_vertexTOFmatched"), bcInTF, occupancy); @@ -1049,7 +1080,7 @@ struct DetectorOccupancyQaTask { // nPV++; // July 2025: more for data vs MC: - if (track.hasTPC() && occupancy >= 0) { + if (track.hasTPC() && occupancy >= 0 && confAddBasicQAhistos) { float pt = track.pt(); // pt 0.2-0.5 if (pt > 0.2 && pt < 0.5) { @@ -1093,7 +1124,7 @@ struct DetectorOccupancyQaTask { nGlobalTracks++; histos.fill(HIST("nTrackCounter_after_cuts_QA"), 5); - if (track.passedTPCRefit()) { + if (track.passedTPCRefit() && confAddBasicQAhistos) { histos.fill(HIST("nTrackCounter_after_cuts_QA"), 6); float signedP = track.sign() * track.tpcInnerParam(); @@ -1228,7 +1259,7 @@ struct DetectorOccupancyQaTask { // continue; histos.fill(HIST("hOccupancy"), occupancy); - if (occupancy >= 0) { + if (occupancy >= 0 && confAddBasicQAhistos) { int orbitId = bcInTF / o2::constants::lhc::LHCMaxBunches; histos.fill(HIST("hOccupancyVsOrbit"), orbitId, occupancy); } @@ -1448,6 +1479,51 @@ struct DetectorOccupancyQaTask { } // end of spec track loop to fill track histograms } // end of if (confAddBasicQAhistos) + // special loop to fill THn histograms + if (confFlagFillTHn && occupancy >= 0) { + for (const auto& track : tracksGrouped) { + if (!track.isPVContributor()) + continue; + if (track.itsNCls() < confMinITSclsPerTrack) + continue; + + float pt = track.pt(); + float eta = track.eta(); + + if (fabs(eta) > 0.8) + continue; + if (pt < 0.15) + continue; + + bool hasTPCspecCuts = (track.hasTPC() && track.tpcNClsFound() >= confCutMinTPCcls && track.tpcNClsCrossedRows() > 80 && track.tpcChi2NCl() < 4); + if (!hasTPCspecCuts) + continue; + + float sign = track.sign(); + // if (sign < 0) + // continue; + + float qpt = track.signed1Pt(); + + // fill THnF: + for (int iRadius = 0; iRadius < 8; iRadius++) { + float R = (iRadius == 0 ? 0 : 0.8 + iRadius * 0.2); // cm + float phiAtR = track.phi(); + if (iRadius > 0) { + histos.fill(HIST("THnD_histos/QA_under_asin"), R / 2 * 0.3 * sign * 0.5 / pt); + histos.fill(HIST("THnD_histos/QA_asin"), asin(R / 2 * 0.3 * sign * 0.5 / pt)); + + phiAtR -= asin(R / 2 * 0.3 * sign * 0.5 / pt); + if (phiAtR < 0) + phiAtR += TMath::TwoPi(); + else if (phiAtR > TMath::TwoPi()) + phiAtR -= TMath::TwoPi(); + } + histos.fill(HIST("THnD_histos/phi_R_qOp_IR_occ_centr_eta"), phiAtR, iRadius, qpt, IR, occupancy, nPV, eta); + } + } + } // end of confFlagFillTHn + // occupancy vs centrality if (confFlagCentralityIsAvailable) { auto t0cCentr = col.centFT0C(); diff --git a/DPG/Tasks/ITS/itsImpParStudies.cxx b/DPG/Tasks/ITS/itsImpParStudies.cxx index 67fba3b4989..7635ed3290a 100644 --- a/DPG/Tasks/ITS/itsImpParStudies.cxx +++ b/DPG/Tasks/ITS/itsImpParStudies.cxx @@ -10,33 +10,32 @@ // or submit itself to any jurisdiction. /// \author Samuele Cattaruzzi -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/DCA.h" +#include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" // for propagation to primary vertex - #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "CommonUtils/NameConf.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/Core/TrackSelection.h" -#include "DetectorsVertexing/PVertexer.h" -#include "ReconstructionDataFormats/Vertex.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/RunningWorkflowInfo.h" #include "CCDB/CcdbApi.h" -#include "DataFormatsCalibration/MeanVertexObject.h" #include "CommonConstants/GeomConstants.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexer.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "ReconstructionDataFormats/DCA.h" +#include "ReconstructionDataFormats/Vertex.h" #include "iostream" -#include "vector" #include "set" +#include "vector" +#include using namespace o2::framework; using namespace o2::framework::expressions; @@ -490,7 +489,7 @@ struct ItsImpactParStudies { continue; } auto particle = track.mcParticle(); - if (keepOnlyPhysPrimary && particle.isPhysicalPrimary()) { + if (keepOnlyPhysPrimary && !(particle.isPhysicalPrimary())) { continue; } histograms.fill(HIST("MC/ptMC"), particle.pt()); diff --git a/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h index 8fe58ce9d7b..73350e81c6c 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h @@ -41,7 +41,7 @@ class FemtoDreamCollisionSelection /// \param checkTrigger whether or not to check for the trigger alias /// \param trig Requested trigger alias /// \param checkOffline whether or not to check for offline selection criteria - void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool addCheckOffline, bool checkRun3) + void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool addCheckOffline, bool checkRun3, float minSphericity, float sphericityPtmin) { mCutsSet = true; mZvtxMax = zvtxMax; @@ -50,6 +50,8 @@ class FemtoDreamCollisionSelection mCheckOffline = checkOffline; mAddCheckOffline = addCheckOffline; mCheckIsRun3 = checkRun3; + mMinSphericity = minSphericity; + mSphericityPtmin = sphericityPtmin; } /// Initializes histograms for the task @@ -66,6 +68,7 @@ class FemtoDreamCollisionSelection mHistogramRegistry->add("Event/MultNTracksPV", "; MultNTracksPV; Entries", kTH1F, {{200, 0, 200}}); mHistogramRegistry->add("Event/MultNTracklets", "; MultNTrackslets; Entries", kTH1F, {{300, 0, 300}}); mHistogramRegistry->add("Event/MultTPC", "; MultTPC; Entries", kTH1F, {{600, 0, 600}}); + mHistogramRegistry->add("Event/Sphericity", "; Sphericity; Entries", kTH1F, {{100, 0, 1}}); } /// Print some debug information @@ -76,6 +79,8 @@ class FemtoDreamCollisionSelection LOG(info) << "Check trigger: " << mCheckTrigger; LOG(info) << "Trigger: " << mTrigger; LOG(info) << " Check offline: " << mCheckOffline; + LOG(info) << "Min sphericity: " << mMinSphericity; + LOG(info) << "Min Pt (sphericity): " << mSphericityPtmin; } /// Check whether the collisions fulfills the specified selections @@ -180,9 +185,65 @@ class FemtoDreamCollisionSelection /// \param tracks All tracks /// \return value of the sphericity of the event template - float computeSphericity(T1 const& /*col*/, T2 const& /*tracks*/) + float computeSphericity(T1 const& col, T2 const& tracks) { - return 2.f; + double ptTot = 0.; + double s00 = 0.; // elements of the sphericity matrix taken form EPJC72:2124 + double s01 = 0.; + // double s10 = 0.; + double s11 = 0.; + + int numOfTracks = col.numContrib(); + if (numOfTracks < 3) + return -9999.; + + for (auto const& track : tracks) { + double pt = track.pt(); + double eta = track.eta(); + double px = track.px(); + double py = track.py(); + if (TMath::Abs(pt) < mSphericityPtmin || TMath::Abs(eta) > 0.8) { + continue; + } + + ptTot += pt; + + s00 += px * px / pt; + s01 += px * py / pt; + // s10 = s01; + s11 += py * py / pt; + } + + // normalize to total Pt to obtain a linear form: + if (ptTot == 0.) + return -9999.; + s00 /= ptTot; + s11 /= ptTot; + s01 /= ptTot; + + // Calculate the trace of the sphericity matrix: + double T = s00 + s11; + // Calculate the determinant of the sphericity matrix: + double D = s00 * s11 - s01 * s01; // S10 = S01 + + // Calculate the eigenvalues of the sphericity matrix: + double lambda1 = 0.5 * (T + std::sqrt(T * T - 4. * D)); + double lambda2 = 0.5 * (T - std::sqrt(T * T - 4. * D)); + + if ((lambda1 + lambda2) == 0.) + return -9999.; + + double spt = -1.; + + if (lambda2 > lambda1) { + spt = 2. * lambda1 / (lambda1 + lambda2); + } else { + spt = 2. * lambda2 / (lambda1 + lambda2); + } + + mHistogramRegistry->fill(HIST("Event/Sphericity"), spt); + + return spt; } private: @@ -194,6 +255,8 @@ class FemtoDreamCollisionSelection bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam triggerAliases mTrigger = kINT7; ///< Trigger to check for float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) + float mMinSphericity = 0.f; + float mSphericityPtmin = 0.f; }; } // namespace o2::analysis::femtoDream diff --git a/PWGCF/FemtoDream/TableProducer/CMakeLists.txt b/PWGCF/FemtoDream/TableProducer/CMakeLists.txt index 77ece58f958..3af1c541683 100644 --- a/PWGCF/FemtoDream/TableProducer/CMakeLists.txt +++ b/PWGCF/FemtoDream/TableProducer/CMakeLists.txt @@ -14,11 +14,6 @@ o2physics_add_dpl_workflow(femtodream-producer PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(femtodream-producer-withcascades - SOURCES femtoDreamProducerTaskWithCascades.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::EventFilteringUtils - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(femtodream-producer-reduced SOURCES femtoDreamProducerReducedTask.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx index a879a18517f..a1cd73cbf6f 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx @@ -79,6 +79,8 @@ struct femtoDreamProducerReducedTask { Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; Configurable ConfEvtAddOfflineCheck{"ConfEvtAddOfflineCheck", false, "Evt sel: additional checks for offline selection (not part of sel8 yet)"}; + Configurable ConfEvtMinSphericity{"ConfEvtMinSphericity", 0.0f, "Evt sel: Min. sphericity of event"}; + Configurable ConfEvtSphericityPtmin{"ConfEvtSphericityPtmin", 0.0f, "Evt sel: Min. Pt for sphericity calculation"}; Configurable ConfTrkRejectNotPropagated{"ConfTrkRejectNotPropagated", false, "True: reject not propagated tracks"}; @@ -116,7 +118,7 @@ struct femtoDreamProducerReducedTask { int CutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); Registry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); - colCuts.setCuts(ConfEvtZvtx.value, ConfEvtTriggerCheck.value, ConfEvtTriggerSel.value, ConfEvtOfflineCheck.value, ConfEvtAddOfflineCheck.value, ConfIsRun3.value); + colCuts.setCuts(ConfEvtZvtx.value, ConfEvtTriggerCheck.value, ConfEvtTriggerSel.value, ConfEvtOfflineCheck.value, ConfEvtAddOfflineCheck.value, ConfIsRun3.value, ConfEvtMinSphericity.value, ConfEvtSphericityPtmin.value); colCuts.init(&qaRegistry); trackCuts.setSelection(ConfTrkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index 0e190295508..f311518c56b 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -131,6 +131,8 @@ struct femtoDreamProducerTask { Configurable ConfEvtAddOfflineCheck{"ConfEvtAddOfflineCheck", false, "Evt sel: additional checks for offline selection (not part of sel8 yet)"}; Configurable ConfIsActivateV0{"ConfIsActivateV0", true, "Activate filling of V0 into femtodream tables"}; Configurable ConfIsActivateReso{"ConfIsActivateReso", false, "Activate filling of sl Resonances into femtodream tables"}; + Configurable ConfEvtMinSphericity{"ConfEvtMinSphericity", 0.0f, "Evt sel: Min. sphericity of event"}; + Configurable ConfEvtSphericityPtmin{"ConfEvtSphericityPtmin", 0.0f, "Evt sel: Min. Pt for sphericity calculation"}; Configurable ConfTrkRejectNotPropagated{"ConfTrkRejectNotPropagated", false, "True: reject not propagated tracks"}; // Configurable ConfRejectITSHitandTOFMissing{ "ConfRejectITSHitandTOFMissing", false, "True: reject if neither ITS hit nor TOF timing satisfied"}; @@ -270,7 +272,7 @@ struct femtoDreamProducerTask { rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, false, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); - colCuts.setCuts(ConfEvtZvtx.value, ConfEvtTriggerCheck.value, ConfEvtTriggerSel.value, ConfEvtOfflineCheck.value, ConfEvtAddOfflineCheck.value, ConfIsRun3.value); + colCuts.setCuts(ConfEvtZvtx.value, ConfEvtTriggerCheck.value, ConfEvtTriggerSel.value, ConfEvtOfflineCheck.value, ConfEvtAddOfflineCheck.value, ConfIsRun3.value, ConfEvtMinSphericity.value, ConfEvtSphericityPtmin.value); colCuts.init(&qaRegistry); trackCuts.setSelection(ConfTrkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskWithCascades.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskWithCascades.cxx deleted file mode 100644 index a7e02ec87e6..00000000000 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskWithCascades.cxx +++ /dev/null @@ -1,1173 +0,0 @@ -// Copyright 2019-2025 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 femtoDreamProducerTaskWithCascades.cxx -/// \brief Tasks that produces the track tables used for the pairing -/// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de - -#include -#include -#include -#include -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/PIDResponseITS.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "EventFiltering/Zorro.h" -#include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "ReconstructionDataFormats/Track.h" -#include "TMath.h" -#include "Math/Vector4D.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::analysis::femtoDream; - -namespace o2::aod -{ - -using FemtoFullCollision = soa::Join::iterator; -using FemtoFullCollision_noCent = soa::Join::iterator; -using FemtoFullCollision_CentPbPb = soa::Join::iterator; -using FemtoFullCollisionMC = soa::Join::iterator; -using FemtoFullCollision_noCent_MC = soa::Join::iterator; -using FemtoFullCollisionMC_CentPbPb = soa::Join::iterator; -using FemtoFullMCgenCollisions = soa::Join; -using FemtoFullMCgenCollision = FemtoFullMCgenCollisions::iterator; - -using FemtoFullTracks = - soa::Join; -} // namespace o2::aod - -namespace softwareTriggers -{ -static const int nTriggers = 6; -static const std::vector triggerNames{"fPPP", "fPPL", "fPLL", "fLLL", "fPD", "fLD"}; -static const float triggerSwitches[1][nTriggers]{ - {0, 0, 0, 0, 0, 0}}; -} // namespace softwareTriggers - -template -int getRowDaughters(int daughID, T const& vecID) -{ - int rowInPrimaryTrackTableDaugh = -1; - for (size_t i = 0; i < vecID.size(); i++) { - if (vecID.at(i) == daughID) { - rowInPrimaryTrackTableDaugh = i; - break; - } - } - return rowInPrimaryTrackTableDaugh; -} - -struct femtoDreamProducerTaskWithCascades { - - Zorro zorro; - - Produces outputCollision; - Produces outputMCCollision; - Produces outputCollsMCLabels; - Produces outputParts; - Produces outputPartsMC; - Produces outputDebugParts; - Produces outputPartsMCLabels; - Produces outputDebugPartsMC; - Produces outputPartsExtMCLabels; - - Configurable ConfIsDebug{"ConfIsDebug", true, "Enable Debug tables"}; - Configurable ConfUseItsPid{"ConfUseItsPid", false, "Enable Debug tables"}; - Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Run3 or pilot"}; - Configurable ConfIsForceGRP{"ConfIsForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; - /// Event cuts - FemtoDreamCollisionSelection colCuts; - // Event cuts - Triggers - Configurable ConfEnableTriggerSelection{"ConfEnableTriggerSelection", false, "Should the trigger selection be enabled for collisions?"}; - Configurable> ConfTriggerSwitches{ - "ConfTriggerSwitches", - {softwareTriggers::triggerSwitches[0], 1, softwareTriggers::nTriggers, std::vector{"Switch"}, softwareTriggers::triggerNames}, - "Turn on which trigger should be checked for recorded events to pass selection"}; - Configurable ConfBaseCCDBPathForTriggers{"ConfBaseCCDBPathForTriggers", "Users/m/mpuccio/EventFiltering/OTS/Chunked/", "Provide ccdb path for trigger table; default - trigger coordination"}; - - // Event cuts - usual selection criteria - Configurable ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; - Configurable ConfEvtTriggerCheck{"ConfEvtTriggerCheck", true, "Evt sel: check for trigger"}; - Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; - Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; - Configurable ConfEvtAddOfflineCheck{"ConfEvtAddOfflineCheck", false, "Evt sel: additional checks for offline selection (not part of sel8 yet)"}; - Configurable ConfIsActivateV0{"ConfIsActivateV0", true, "Activate filling of V0 into femtodream tables"}; - Configurable ConfIsActivateReso{"ConfIsActivateReso", false, "Activate filling of sl Resonances into femtodream tables"}; - Configurable ConfIsActivateCascade{"ConfIsActivateCascade", false, "Activate filling of Cascades into femtodream tables"}; - - Configurable ConfTrkRejectNotPropagated{"ConfTrkRejectNotPropagated", false, "True: reject not propagated tracks"}; - // Configurable ConfRejectITSHitandTOFMissing{ "ConfRejectITSHitandTOFMissing", false, "True: reject if neither ITS hit nor TOF timing satisfied"}; - Configurable ConfTrkPDGCode{"ConfTrkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; - FemtoDreamTrackSelection trackCuts; - Configurable> ConfTrkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "ConfTrk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; - Configurable> ConfTrkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "ConfTrk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; - Configurable> ConfTrkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "ConfTrk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; - Configurable> ConfTrkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "ConfTrk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> ConfTrkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "ConfTrk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; - Configurable> ConfTrkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "ConfTrk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; - Configurable> ConfTrkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "ConfTrk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; - Configurable> ConfTrkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "ConfTrk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; - Configurable> ConfTrkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "ConfTrk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; - Configurable> ConfTrkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "ConfTrk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; - Configurable> ConfTrkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "ConfTrk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; - Configurable> ConfTrkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "ConfTrk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; - Configurable> ConfTrkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "ConfTrk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; - Configurable ConfTrkPIDnSigmaOffsetTPC{"ConfTrkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; - Configurable ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; - - FemtoDreamV0Selection v0Cuts; - Configurable> ConfV0Sign{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0Sign, "ConfV0"), std::vector{-1, 1}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0Sign, "V0 selection: ")}; - Configurable> ConfV0PtMin{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0pTMin, "ConfV0"), std::vector{0.3f, 0.4f, 0.5f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0pTMin, "V0 selection: ")}; - Configurable> ConfV0PtMax{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0pTMax, "ConfV0"), std::vector{3.3f, 3.4f, 3.5f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0pTMax, "V0 selection: ")}; - Configurable> ConfV0EtaMax{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0etaMax, "ConfV0"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0etaMax, "V0 selection: ")}; - Configurable> ConfV0DCADaughMax{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0DCADaughMax, "ConfV0"), std::vector{1.2f, 1.5f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0DCADaughMax, "V0 selection: ")}; - Configurable> ConfV0CPAMin{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0CPAMin, "ConfV0"), std::vector{0.99f, 0.995f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0CPAMin, "V0 selection: ")}; - Configurable> ConfV0TranRadMin{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0TranRadMin, "ConfV0"), std::vector{0.2f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0TranRadMin, "V0 selection: ")}; - Configurable> ConfV0TranRadMax{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0TranRadMax, "ConfV0"), std::vector{100.f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0TranRadMax, "V0 selection: ")}; - Configurable> ConfV0DecVtxMax{FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0DecVtxMax, "ConfV0"), std::vector{100.f}, FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0DecVtxMax, "V0 selection: ")}; - - Configurable ConfV0InvMassLowLimit{"ConfV0InvV0MassLowLimit", 1.05, "Lower limit of the V0 invariant mass"}; - Configurable ConfV0InvMassUpLimit{"ConfV0InvV0MassUpLimit", 1.30, "Upper limit of the V0 invariant mass"}; - Configurable ConfV0RejectKaons{"ConfV0RejectKaons", false, "Switch to reject kaons"}; - Configurable ConfV0InvKaonMassLowLimit{"ConfV0InvKaonMassLowLimit", 0.48, "Lower limit of the V0 invariant mass for Kaon rejection"}; - Configurable ConfV0InvKaonMassUpLimit{"ConfV0InvKaonMassUpLimit", 0.515, "Upper limit of the V0 invariant mass for Kaon rejection"}; - - Configurable> ConfChildCharge{"ConfChildSign", std::vector{-1, 1}, "V0 Child sel: Charge"}; - Configurable> ConfChildEtaMax{"ConfChildEtaMax", std::vector{0.8f}, "V0 Child sel: max eta"}; - Configurable> ConfChildTPCnClsMin{"ConfChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "V0 Child sel: Min. nCls TPC"}; - Configurable> ConfChildDCAMin{"ConfChildDCAMin", std::vector{0.05f, 0.06f}, "V0 Child sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{5.f, 4.f}, "V0 Child sel: Max. PID nSigma TPC"}; - Configurable> ConfChildPIDspecies{"ConfChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "V0 Child sel: Particles species for PID"}; - - FemtoDreamCascadeSelection cascadeCuts; - struct : o2::framework::ConfigurableGroup { - Configurable ConfCascInvMassLowLimit{"ConfCascInvMassLowLimit", 1.2, "Lower limit of the Cascade invariant mass"}; - Configurable ConfCascInvMassUpLimit{"ConfCascInvMassUpLimit", 1.5, "Upper limit of the Cascade invariant mass"}; - Configurable ConfCascIsSelectedOmega{"ConfCascIsSelectedOmega", false, "Select Omegas instead of Xis (invariant mass)"}; - // Cascade - Configurable> ConfCascadeSign{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeSign, "ConfCascade"), std::vector{-1, 1}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeSign, "Cascade selection: ")}; - Configurable> ConfCascadePtMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadePtMin, "ConfCascade"), std::vector{0.3f, 0.4f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadePtMin, "Cascade selection: ")}; - Configurable> ConfCascadePtMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadePtMax, "ConfCascade"), std::vector{5.5f, 6.0f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadePtMax, "Cascade selection: ")}; - Configurable> ConfCascadeEtaMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeEtaMax, "ConfCascade"), std::vector{0.8f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeEtaMax, "Cascade selection: ")}; - Configurable> ConfCascadeDCADaughMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDCADaughMax, "ConfCascade"), std::vector{1.f, 1.2f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDCADaughMax, "Cascade selection: ")}; - Configurable> ConfCascadeCPAMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeCPAMin, "ConfCascade"), std::vector{0.99f, 0.95f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeCPAMin, "Cascade selection: ")}; - Configurable> ConfCascadeTranRadMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeTranRadMin, "ConfCascade"), std::vector{0.2f, 0.5f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeTranRadMin, "Cascade selection: ")}; - Configurable> ConfCascadeTranRadMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeTranRadMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeTranRadMax, "Cascade selection: ")}; - Configurable> ConfCascadeDecVtxMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDecVtxMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDecVtxMax, "Cascade selection: ")}; - - // Cascade v0 daughters - Configurable> ConfCascadeV0DCADaughMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0DCADaughMax, "ConfCascade"), std::vector{1.2f, 1.5f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0DCADaughMax, "CascV0 selection: ")}; - Configurable> ConfCascadeV0CPAMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0CPAMin, "ConfCascade"), std::vector{0.99f, 0.995f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0CPAMin, "CascV0 selection: ")}; - Configurable> ConfCascadeV0TranRadMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0TranRadMin, "ConfCascade"), std::vector{0.2f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0TranRadMin, "CascV0 selection: ")}; - Configurable> ConfCascadeV0TranRadMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0TranRadMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0TranRadMax, "CascV0 selection: ")}; - Configurable> ConfCascadeV0DCAtoPVMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, "CascV0 selection: ")}; - Configurable> ConfCascadeV0DCAtoPVMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, "CascV0 selection: ")}; - Configurable ConfCascV0InvMassLowLimit{"ConfCascV0InvMassLowLimit", 1.011461, "Lower limit of the Cascade invariant mass"}; - Configurable ConfCascV0InvMassUpLimit{"ConfCascV0InvMassUpLimit", 1.027461, "Upper limit of the Cascade invariant mass"}; - // Cascade Daughter Tracks - Configurable> ConfCascV0ChildCharge{"ConfCascV0ChildSign", std::vector{-1, 1}, "CascV0 Child sel: Charge"}; - Configurable> ConfCascV0ChildPtMin{"ConfCascV0ChildPtMin", std::vector{0.8f}, "CascV0 Child sel: min pt"}; - Configurable> ConfCascV0ChildEtaMax{"ConfCascV0ChildEtaMax", std::vector{0.8f}, "CascV0 Child sel: max eta"}; - Configurable> ConfCascV0ChildTPCnClsMin{"ConfCascV0ChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "CascV0 Child sel: Min. nCls TPC"}; - Configurable> ConfCascV0ChildDCAMin{"ConfCascV0ChildDCAMin", std::vector{0.05f, 0.06f}, "CascV0 Child sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfCascV0ChildPIDnSigmaMax{"ConfCascV0ChildPIDnSigmaMax", std::vector{5.f, 4.f}, "CascV0 Child sel: Max. PID nSigma TPC"}; - Configurable> ConfCascV0ChildPIDspecies{"ConfCascV0ChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "CascV0 Child sel: Particles species for PID"}; - // Cascade Bachelor Track - Configurable> ConfCascBachelorCharge{"ConfCascBachelorSign", std::vector{-1, 1}, "Cascade Bachelor sel: Charge"}; - Configurable> ConfCascBachelorPtMin{"ConfCascBachelorPtMin", std::vector{0.8f}, "Cascade Bachelor sel: min pt"}; - Configurable> ConfCascBachelorEtaMax{"ConfCascBachelorEtaMax", std::vector{0.8f}, "Cascade Bachelor sel: max eta"}; - Configurable> ConfCascBachelorTPCnClsMin{"ConfCascBachelorTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "Cascade Bachelor sel: Min. nCls TPC"}; - Configurable> ConfCascBachelorDCAMin{"ConfCascBachelorDCAMin", std::vector{0.05f, 0.06f}, "Cascade Bachelor sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfCascBachelorPIDnSigmaMax{"ConfCascBachelorPIDnSigmaMax", std::vector{5.f, 4.f}, "Cascade Bachelor sel: Max. PID nSigma TPC"}; - Configurable> ConfCascBachelorPIDspecies{"ConfCascBachelorPIDspecies", std::vector{o2::track::PID::Pion}, "Cascade Bachelor sel: Particles species for PID"}; - - Configurable ConfCascRejectCompetingMass{"ConfCascRejectCompetingMass", false, "Switch on to reject Omegas (for Xi) or Xis (for Omegas)"}; - Configurable ConfCascInvCompetingMassLowLimit{"ConfCascInvCompetingMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for competing mass rejection"}; - Configurable ConfCascInvCompetingMassUpLimit{"ConfCascInvCompetingMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for competing mass rejection"}; - - } ConfCascSel; - - // Resonances - Configurable ConfResoInvMassLowLimit{"ConfResoInvMassLowLimit", 1.011461, "Lower limit of the Reso invariant mass"}; - Configurable ConfResoInvMassUpLimit{"ConfResoInvMassUpLimit", 1.027461, "Upper limit of the Reso invariant mass"}; - Configurable> ConfDaughterCharge{"ConfDaughterCharge", std::vector{1, -1}, "Reso Daughter sel: Charge"}; - Configurable> ConfDaughterEta{"ConfDaughterEta", std::vector{0.8, 0.8}, "Reso Daughter sel: Eta"}; // 0.8 - Configurable> ConfDaughterDCAxy{"ConfDaughterDCAxy", std::vector{0.1, 0.1}, "Reso Daughter sel: DCAxy"}; // 0.1 - Configurable> ConfDaughterDCAz{"ConfDaughterDCAz", std::vector{0.2, 0.2}, "Reso Daughter sel: DCAz"}; // 0.2 - Configurable> ConfDaughterNClus{"ConfDaughterNClus", std::vector{80, 80}, "Reso Daughter sel: NClusters"}; // 0.2 - Configurable> ConfDaughterNCrossed{"ConfDaughterNCrossed", std::vector{70, 70}, "Reso Daughter sel: NCrossedRowss"}; - Configurable> ConfDaughterTPCfCls{"ConfDaughterTPCfCls", std::vector{0.8, 0.8}, "Reso Daughter sel: Minimum fraction of crossed rows over findable cluster"}; // 0.2 - Configurable> ConfDaughterPtUp{"ConfDaughterPtUp", std::vector{2.0, 2.0}, "Reso Daughter sel: Upper limit pT"}; // 2.0 - Configurable> ConfDaughterPtLow{"ConfDaughterPtLow", std::vector{0.15, 0.15}, "Reso Daughter sel: Lower limit pT"}; // 0.15 - Configurable> ConfDaughterPTPCThr{"ConfDaughterPTPCThr", std::vector{0.40, 0.40}, "Reso Daughter sel: momentum threshold TPC only PID, p_TPC,Thr"}; // 0.4 - Configurable> ConfDaughterPIDnSigmaMax{"ConfDaughterPIDnSigmaMax", std::vector{3.00, 3.00}, "Reso Daughter sel: Max. PID nSigma TPC"}; // 3.0 - Configurable> ConfDaughterPIDspecies{"ConfDaughterPIDspecies", std::vector{o2::track::PID::Kaon, o2::track::PID::Kaon}, "Reso Daughter sel: Particles species for PID"}; - Configurable> ConfDaug1Daugh2ResoMass{"ConfDaug1Daugh2ResoMass", std::vector{o2::constants::physics::MassKPlus, o2::constants::physics::MassKMinus, o2::constants::physics::MassPhi}, "Masses: Daughter1 - Daughter2 - Resonance"}; - - /// \todo should we add filter on min value pT/eta of V0 and daughters? - /*Filter v0Filter = (nabs(aod::v0data::x) < V0DecVtxMax.value) && - (nabs(aod::v0data::y) < V0DecVtxMax.value) && - (nabs(aod::v0data::z) < V0DecVtxMax.value);*/ - // (aod::v0data::v0radius > V0TranRadV0Min.value); to be added, not working - // for now do not know why - - /// General options - struct : o2::framework::ConfigurableGroup { - Configurable ConfTrkMinChi2PerClusterTPC{"ConfTrkMinChi2PerClusterTPC", 0.f, "Lower limit for chi2 of TPC; currently for testing only"}; - Configurable ConfTrkMaxChi2PerClusterTPC{"ConfTrkMaxChi2PerClusterTPC", 1000.f, "Upper limit for chi2 of TPC; currently for testing only"}; - Configurable ConfTrkMaxChi2PerClusterITS{"ConfTrkMaxChi2PerClusterITS", 1000.0f, "Minimal track selection: max allowed chi2 per ITS cluster"}; // 36.0 is default - Configurable ConfTrkTPCRefit{"ConfTrkTPCRefit", false, "True: require TPC refit"}; - Configurable ConfTrkITSRefit{"ConfTrkITSRefit", false, "True: require ITS refit"}; - - } OptionTrackSpecialSelections; - - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry TrackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry V0Registry{"V0", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry ResoRegistry{"Reso", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry CascadeRegistry{"Cascade", {}, OutputObjHandlingPolicy::AnalysisObject}; - - int mRunNumber; - float mMagField; - std::string zorroTriggerNames = ""; - Service ccdb; /// Accessing the CCDB - - void init(InitContext&) - { - if (doprocessData == false && doprocessData_noCentrality == false && doprocessData_CentPbPb == false && doprocessMC == false && doprocessMC_noCentrality == false && doprocessMC_CentPbPb == false) { - LOGF(fatal, "Neither processData nor processMC enabled. Please choose one."); - } - if ((doprocessData == true && doprocessMC == true) || (doprocessData == true && doprocessMC_noCentrality == true) || (doprocessMC == true && doprocessMC_noCentrality == true) || (doprocessData_noCentrality == true && doprocessData == true) || (doprocessData_noCentrality == true && doprocessMC == true) || (doprocessData_noCentrality == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessData == true) || (doprocessData_CentPbPb == true && doprocessData_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessMC == true) || (doprocessData_CentPbPb == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessMC_CentPbPb == true)) { - LOGF(fatal, - "Cannot enable more than one process switch at the same time. " - "Please choose one."); - } - - int CutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); - TrackRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); - TrackRegistry.add("AnalysisQA/Chi2ITSTPCperCluster", "; ITS_Chi2; TPC_Chi2", kTH2F, {{100, 0, 50}, {100, 0, 20}}); - TrackRegistry.add("AnalysisQA/RefitITSTPC", "; ITS_Refit; TPC_Refit", kTH2F, {{2, 0, 2}, {2, 0, 2}}); - TrackRegistry.add("AnalysisQA/getGenStatusCode", "; Bit; Entries", kTH1F, {{200, 0, 200}}); - TrackRegistry.add("AnalysisQA/getProcess", "; Bit; Entries", kTH1F, {{200, 0, 200}}); - TrackRegistry.add("AnalysisQA/Mother", "; Bit; Entries", kTH1F, {{4000, -4000, 4000}}); - TrackRegistry.add("AnalysisQA/Particle", "; Bit; Entries", kTH1F, {{4000, -4000, 4000}}); - V0Registry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); - CascadeRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); - ResoRegistry.add("AnalysisQA/Reso/InvMass", "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {{7000, 0.8, 1.5}}); - ResoRegistry.add("AnalysisQA/Reso/InvMass_selected", "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {{7000, 0.8, 1.5}}); - ResoRegistry.add("AnalysisQA/Reso/Daughter1/Pt", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - ResoRegistry.add("AnalysisQA/Reso/Daughter1/Eta", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{1000, -2, 2}}); - ResoRegistry.add("AnalysisQA/Reso/Daughter1/Phi", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - ResoRegistry.add("AnalysisQA/Reso/Daughter2/Pt", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - ResoRegistry.add("AnalysisQA/Reso/Daughter2/Eta", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{1000, -2, 2}}); - ResoRegistry.add("AnalysisQA/Reso/Daughter2/Phi", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - ResoRegistry.add("AnalysisQA/Reso/PtD1_selected", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - ResoRegistry.add("AnalysisQA/Reso/PtD2_selected", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - - if (ConfEnableTriggerSelection) { - for (const std::string& triggerName : softwareTriggers::triggerNames) { - if (ConfTriggerSwitches->get("Switch", triggerName.c_str())) { - zorroTriggerNames += triggerName + ","; - } - } - zorroTriggerNames.pop_back(); - } - - colCuts.setCuts(ConfEvtZvtx.value, ConfEvtTriggerCheck.value, ConfEvtTriggerSel.value, ConfEvtOfflineCheck.value, ConfEvtAddOfflineCheck.value, ConfIsRun3.value); - colCuts.init(&qaRegistry); - - trackCuts.setSelection(ConfTrkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - trackCuts.setSelection(ConfTrkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(ConfTrkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(ConfTrkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(ConfTrkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(ConfTrkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(ConfTrkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setPIDSpecies(ConfTrkPIDspecies); - trackCuts.setnSigmaPIDOffset(ConfTrkPIDnSigmaOffsetTPC, ConfTrkPIDnSigmaOffsetTOF); - trackCuts.init(&qaRegistry, &TrackRegistry); - - /// \todo fix how to pass array to setSelection, getRow() passing a - /// different type! - // v0Cuts.setSelection(ConfV0Selection->getRow(0), - // femtoDreamV0Selection::kDecVtxMax, femtoDreamSelection::kAbsUpperLimit); - if (ConfIsActivateV0) { - v0Cuts.setSelection(ConfV0Sign, femtoDreamV0Selection::kV0Sign, femtoDreamSelection::kEqual); - v0Cuts.setSelection(ConfV0PtMin, femtoDreamV0Selection::kV0pTMin, femtoDreamSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0PtMax, femtoDreamV0Selection::kV0pTMax, femtoDreamSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0EtaMax, femtoDreamV0Selection::kV0etaMax, femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setSelection(ConfV0DCADaughMax, femtoDreamV0Selection::kV0DCADaughMax, femtoDreamSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0CPAMin, femtoDreamV0Selection::kV0CPAMin, femtoDreamSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0TranRadMin, femtoDreamV0Selection::kV0TranRadMin, femtoDreamSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0TranRadMax, femtoDreamV0Selection::kV0TranRadMax, femtoDreamSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0DecVtxMax, femtoDreamV0Selection::kV0DecVtxMax, femtoDreamSelection::kUpperLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kAbsLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kAbsLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildPIDSpecies(femtoDreamV0Selection::kPosTrack, ConfChildPIDspecies); - v0Cuts.setChildPIDSpecies(femtoDreamV0Selection::kNegTrack, ConfChildPIDspecies); - v0Cuts.init(&qaRegistry, &V0Registry); - v0Cuts.setInvMassLimits(ConfV0InvMassLowLimit, ConfV0InvMassUpLimit); - - v0Cuts.setChildRejectNotPropagatedTracks(femtoDreamV0Selection::kPosTrack, ConfTrkRejectNotPropagated); - v0Cuts.setChildRejectNotPropagatedTracks(femtoDreamV0Selection::kNegTrack, ConfTrkRejectNotPropagated); - - v0Cuts.setnSigmaPIDOffsetTPC(ConfTrkPIDnSigmaOffsetTPC); - v0Cuts.setChildnSigmaPIDOffset(femtoDreamV0Selection::kPosTrack, ConfTrkPIDnSigmaOffsetTPC, ConfTrkPIDnSigmaOffsetTOF); - v0Cuts.setChildnSigmaPIDOffset(femtoDreamV0Selection::kNegTrack, ConfTrkPIDnSigmaOffsetTPC, ConfTrkPIDnSigmaOffsetTOF); - - if (ConfV0RejectKaons) { - v0Cuts.setKaonInvMassLimits(ConfV0InvKaonMassLowLimit, ConfV0InvKaonMassUpLimit); - } - } - if (ConfIsActivateCascade) { - // Cascades - cascadeCuts.setSelection(ConfCascSel.ConfCascadeSign, femtoDreamCascadeSelection::kCascadeSign, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeSign)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadePtMin, femtoDreamCascadeSelection::kCascadePtMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadePtMin)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadePtMax, femtoDreamCascadeSelection::kCascadePtMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadePtMax)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeEtaMax, femtoDreamCascadeSelection::kCascadeEtaMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeEtaMax)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeDCADaughMax, femtoDreamCascadeSelection::kCascadeDCADaughMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeDCADaughMax)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeCPAMin, femtoDreamCascadeSelection::kCascadeCPAMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeCPAMin)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeTranRadMin, femtoDreamCascadeSelection::kCascadeTranRadMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeTranRadMin)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeTranRadMax, femtoDreamCascadeSelection::kCascadeTranRadMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeTranRadMax)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeDecVtxMax, femtoDreamCascadeSelection::kCascadeDecVtxMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeDecVtxMax)); - // Cascade v0 - cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0DCADaughMax, femtoDreamCascadeSelection::kCascadeV0DCADaughMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0DCADaughMax)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0CPAMin, femtoDreamCascadeSelection::kCascadeV0CPAMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0CPAMin)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0TranRadMin, femtoDreamCascadeSelection::kCascadeV0TranRadMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0TranRadMin)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0TranRadMax, femtoDreamCascadeSelection::kCascadeV0TranRadMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0TranRadMax)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0DCAtoPVMin, femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin)); - cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0DCAtoPVMax, femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax)); - - // Cascade Daughter Tracks - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildPtMin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kAbsLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - cascadeCuts.setChildPIDSpecies(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildPIDspecies); - - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildPtMin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kAbsLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - cascadeCuts.setChildPIDSpecies(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildPIDspecies); - - // Cascade Bachelor Track - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorPtMin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kAbsLowerLimit); - cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - cascadeCuts.setChildPIDSpecies(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorPIDspecies); - - cascadeCuts.init(&qaRegistry, &CascadeRegistry, ConfCascSel.ConfCascIsSelectedOmega); - cascadeCuts.setInvMassLimits(ConfCascSel.ConfCascInvMassLowLimit, ConfCascSel.ConfCascInvMassUpLimit); - cascadeCuts.setV0InvMassLimits(ConfCascSel.ConfCascV0InvMassLowLimit, ConfCascSel.ConfCascV0InvMassUpLimit); - if (ConfCascSel.ConfCascRejectCompetingMass) { - cascadeCuts.setCompetingInvMassLimits(ConfCascSel.ConfCascInvCompetingMassLowLimit, ConfCascSel.ConfCascInvCompetingMassUpLimit); - } - } - - mRunNumber = 0; - mMagField = 0.0; - /// Initializing CCDB - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - - int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - ccdb->setCreatedNotAfter(now); - } - - /// Function to retrieve the nominal magnetic field in kG (0.1T) and convert it directly to T - void initCCDB_Mag_Trig(aod::BCsWithTimestamps::iterator bc) - { - // TODO done only once (and not per run). Will be replaced by CCDBConfigurable - // get magnetic field for run - if (mRunNumber == bc.runNumber()) - return; - auto timestamp = bc.timestamp(); - float output = -999; - - if (ConfIsRun3 && !ConfIsForceGRP) { - static o2::parameters::GRPMagField* grpo = nullptr; - grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); - if (grpo == nullptr) { - LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); - return; - } - LOGF(info, "Retrieved GRP for timestamp %llu with L3 ", timestamp, grpo->getL3Current()); - // taken from GRP onject definition of getNominalL3Field; update later to something smarter (mNominalL3Field = std::lround(5.f * mL3Current / 30000.f);) - auto NominalL3Field = std::lround(5.f * grpo->getL3Current() / 30000.f); - output = 0.1 * (NominalL3Field); - - } else { - - static o2::parameters::GRPObject* grpo = nullptr; - grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); - if (grpo == nullptr) { - LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); - return; - } - LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); - output = 0.1 * (grpo->getNominalL3Field()); - } - mMagField = output; - mRunNumber = bc.runNumber(); - - // Init for zorro to get trigger flags - if (ConfEnableTriggerSelection) { - zorro.setCCDBpath(ConfBaseCCDBPathForTriggers); - zorro.initCCDB(ccdb.service, mRunNumber, timestamp, zorroTriggerNames); - } - } - - template - void fillDebugParticle(ParticleType const& particle) - { - if constexpr (isTrackOrV0) { - if constexpr (hasItsPid) { - outputDebugParts(particle.sign(), - (uint8_t)particle.tpcNClsFound(), - particle.tpcNClsFindable(), - (uint8_t)particle.tpcNClsCrossedRows(), - particle.tpcNClsShared(), - particle.tpcInnerParam(), - particle.itsNCls(), - particle.itsNClsInnerBarrel(), - particle.dcaXY(), - particle.dcaZ(), - particle.tpcSignal(), - particle.tpcNSigmaEl(), - particle.tpcNSigmaPi(), - particle.tpcNSigmaKa(), - particle.tpcNSigmaPr(), - particle.tpcNSigmaDe(), - particle.tpcNSigmaTr(), - particle.tpcNSigmaHe(), - particle.tofNSigmaEl(), - particle.tofNSigmaPi(), - particle.tofNSigmaKa(), - particle.tofNSigmaPr(), - particle.tofNSigmaDe(), - particle.tofNSigmaTr(), - particle.tofNSigmaHe(), - o2::analysis::femtoDream::itsSignal(particle), - particle.itsNSigmaEl(), - particle.itsNSigmaPi(), - particle.itsNSigmaKa(), - particle.itsNSigmaPr(), - particle.itsNSigmaDe(), - particle.itsNSigmaTr(), - particle.itsNSigmaHe(), - -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., -999., -999.); - } else { - outputDebugParts(particle.sign(), - (uint8_t)particle.tpcNClsFound(), - particle.tpcNClsFindable(), - (uint8_t)particle.tpcNClsCrossedRows(), - particle.tpcNClsShared(), - particle.tpcInnerParam(), - particle.itsNCls(), - particle.itsNClsInnerBarrel(), - particle.dcaXY(), - particle.dcaZ(), - particle.tpcSignal(), - particle.tpcNSigmaEl(), - particle.tpcNSigmaPi(), - particle.tpcNSigmaKa(), - particle.tpcNSigmaPr(), - particle.tpcNSigmaDe(), - particle.tpcNSigmaTr(), - particle.tpcNSigmaHe(), - particle.tofNSigmaEl(), - particle.tofNSigmaPi(), - particle.tofNSigmaKa(), - particle.tofNSigmaPr(), - particle.tofNSigmaDe(), - particle.tofNSigmaTr(), - particle.tofNSigmaHe(), - -999., -999., -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., -999., -999.); - } - } else { - outputDebugParts(-999., // sign - -999., -999., -999., -999., -999., -999., -999., -999., -999., // track properties (DCA, NCls, crossed rows, etc.) - -999., -999., -999., -999., -999., -999., -999., -999., // TPC PID (TPC signal + particle hypothesis) - -999., -999., -999., -999., -999., -999., -999., // TOF PID - -999., -999., -999., -999., -999., -999., -999., -999., // ITS PID - particle.dcaV0daughters(), - particle.v0radius(), - particle.x(), - particle.y(), - particle.z(), - particle.mK0Short(), - -999., -999., -999., -999., -999., -999., -999.); // Cascade properties - } - } - - template - void fillDebugCascade(ParticleType const& cascade, CollisionType const& col) - { - outputDebugParts(cascade.sign(), // sign - -999., -999., -999., -999., -999., -999., -999., -999., -999., // track properties (DCA, NCls, crossed rows, etc.) - -999., -999., -999., -999., -999., -999., -999., -999., // TPC PID (TPC signal + particle hypothesis) - -999., -999., -999., -999., -999., -999., -999., // TOF PID - -999., -999., -999., -999., -999., -999., -999., -999., // ITS PID - cascade.dcaV0daughters(), - cascade.v0radius(), - -999., // DecVtxV0 x - -999., // DecVtxV0 y - -999., // DecVtxV0 z - -999., // mKaon - cascade.dcav0topv(col.posX(), col.posY(), col.posZ()), - cascade.dcacascdaughters(), - cascade.cascradius(), - cascade.x(), - cascade.y(), - cascade.z(), - cascade.mOmega()); // QA for Reso - } - - template - void fillMCParticle(CollisionType const& col, ParticleType const& particle, o2::aod::femtodreamparticle::ParticleType fdparttype) - { - if (particle.has_mcParticle()) { - // get corresponding MC particle and its info - auto particleMC = particle.mcParticle(); - auto pdgCode = particleMC.pdgCode(); - TrackRegistry.fill(HIST("AnalysisQA/Particle"), pdgCode); - int particleOrigin = 99; - int pdgCodeMother = -1; - // get list of mothers, but it could be empty (for example in case of injected light nuclei) - auto motherparticlesMC = particleMC.template mothers_as(); - // check pdg code - TrackRegistry.fill(HIST("AnalysisQA/getGenStatusCode"), particleMC.getGenStatusCode()); - TrackRegistry.fill(HIST("AnalysisQA/getProcess"), particleMC.getProcess()); - // if this fails, the particle is a fake - if (abs(pdgCode) == abs(ConfTrkPDGCode.value)) { - // check first if particle is from pile up - // check if the collision associated with the particle is the same as the analyzed collision by checking their Ids - if ((col.has_mcCollision() && (particleMC.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kWrongCollision; - // check if particle is primary - } else if (particleMC.isPhysicalPrimary()) { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; - // check if particle is secondary - // particle is from a decay -> getProcess() == 4 - // particle is generated during transport -> getGenStatusCode() == -1 - // list of mothers is not empty - } else if (particleMC.getProcess() == 4 && particleMC.getGenStatusCode() == -1 && !motherparticlesMC.empty()) { - // get direct mother - auto motherparticleMC = motherparticlesMC.front(); - pdgCodeMother = motherparticleMC.pdgCode(); - TrackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); - // check if particle is material - // particle is from inelastic hadronic interaction -> getProcess() == 23 - // particle is generated during transport -> getGenStatusCode() == -1 - } else if (particleMC.getProcess() == 23 && particleMC.getGenStatusCode() == -1) { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; - // cross check to see if we missed a case - } else { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kElse; - } - // if pdg code is wrong, particle is fake - } else { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; - } - - outputPartsMC(particleOrigin, pdgCode, particleMC.pt(), particleMC.eta(), particleMC.phi()); - outputPartsMCLabels(outputPartsMC.lastIndex()); - if (ConfIsDebug) { - outputPartsExtMCLabels(outputPartsMC.lastIndex()); - outputDebugPartsMC(pdgCodeMother); - } - } else { - outputPartsMCLabels(-1); - if (ConfIsDebug) { - outputPartsExtMCLabels(-1); - } - } - } - - template - void fillMCCollision(CollisionType const& col) - { - if (col.has_mcCollision()) { - auto genMCcol = col.template mcCollision_as(); - outputMCCollision(genMCcol.multMCNParticlesEta08()); - outputCollsMCLabels(outputMCCollision.lastIndex()); - } else { - outputCollsMCLabels(-1); - } - } - template - void fillCollisionsAndTracksAndV0AndCascade(CollisionType const& col, TrackType const& tracks, TrackTypeWithItsPid const& tracksWithItsPid, V0Type const& fullV0s, CascadeType const& fullCascades) - { - // If triggering is enabled, select only events which were triggered wit our triggers - if (ConfEnableTriggerSelection) { - bool zorroSelected = zorro.isSelected(col.template bc_as().globalBC()); /// check if event was selected by triggers of interest - if (!zorroSelected) { - return; - } - } - - const auto vtxZ = col.posZ(); - const auto spher = colCuts.computeSphericity(col, tracks); - float mult = 0; - int multNtr = 0; - if (ConfIsRun3) { - if constexpr (useCentrality) { - if constexpr (analysePbPb) { - mult = col.centFT0C(); - } else { - mult = col.centFT0M(); - } - } else { - mult = 0; - } - multNtr = col.multNTracksPV(); - } else { - mult = 1; // multiplicity percentile is know in Run 2 - multNtr = col.multTracklets(); - } - - colCuts.fillQA(col, mult); - - // check whether the basic event selection criteria are fulfilled - // that included checking if there is at least on usable track or V0 - if (!colCuts.isSelectedCollision(col)) { - return; - } - bool emptyCollision = false; - if (ConfIsActivateCascade.value) { - if (colCuts.isEmptyCollision(col, tracks, trackCuts) && colCuts.isCollisionWithoutTrkCasc(col, fullCascades, cascadeCuts, tracks)) { - emptyCollision = true; - } - } - if (ConfIsActivateV0.value) { - if (colCuts.isEmptyCollision(col, tracks, trackCuts) && colCuts.isEmptyCollision(col, fullV0s, v0Cuts, tracks)) { - emptyCollision = true; - } - } else { - if (colCuts.isEmptyCollision(col, tracks, trackCuts)) { - emptyCollision = true; - } - } - if (emptyCollision) { - return; - } - - outputCollision(vtxZ, mult, multNtr, spher, mMagField); - if constexpr (isMC) { - fillMCCollision(col); - } - - std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children - std::vector cascadechildIDs = {0, 0, 0}; // these IDs are necessary to keep track of the children - std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index - std::vector Daughter1, Daughter2; - - for (auto& track : tracksWithItsPid) { - /// if the most open selection criteria are not fulfilled there is no - /// point looking further at the track - trackCuts.fillQA(track); - - if (track.tpcChi2NCl() < OptionTrackSpecialSelections.ConfTrkMinChi2PerClusterTPC || track.tpcChi2NCl() > OptionTrackSpecialSelections.ConfTrkMaxChi2PerClusterTPC) { - continue; - } - if (track.itsChi2NCl() > OptionTrackSpecialSelections.ConfTrkMaxChi2PerClusterITS) { - continue; - } - if ((OptionTrackSpecialSelections.ConfTrkTPCRefit && !track.hasTPC()) || (OptionTrackSpecialSelections.ConfTrkITSRefit && !track.hasITS())) { - continue; - } - - if (!trackCuts.isSelectedMinimal(track)) { - continue; - } - - TrackRegistry.fill(HIST("AnalysisQA/Chi2ITSTPCperCluster"), track.itsChi2NCl(), track.tpcChi2NCl()); - TrackRegistry.fill(HIST("AnalysisQA/RefitITSTPC"), track.hasITS(), track.hasTPC()); - - trackCuts.fillQA(track); - // the bit-wise container of the systematic variations is obtained - std::array cutContainer; - cutContainer = trackCuts.getCutContainer(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f))); - - // now the table is filled - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), - track.dcaXY(), childIDs, 0, 0); - tmpIDtrack.push_back(track.globalIndex()); - if (ConfIsDebug.value) { - fillDebugParticle(track); - } - - if constexpr (isMC) { - fillMCParticle(col, track, o2::aod::femtodreamparticle::ParticleType::kTrack); - } - - if (ConfIsActivateReso.value) { - // Already strict cuts for Daughter of reso selection - // TO DO: change TTV0 task to apply there the strict selection and have here only loose selection - - // select daugher 1 - if (track.sign() == ConfDaughterCharge.value[0] && track.pt() <= ConfDaughterPtUp.value[0] && track.pt() >= ConfDaughterPtLow.value[0] && std::abs(track.eta()) <= ConfDaughterEta.value[0] && std::abs(track.dcaXY()) <= ConfDaughterDCAxy.value[0] && std::abs(track.dcaZ()) <= ConfDaughterDCAz.value[0] && track.tpcNClsCrossedRows() >= ConfDaughterNCrossed.value[0] && track.tpcNClsFound() >= ConfDaughterNClus.value[0] && track.tpcCrossedRowsOverFindableCls() >= ConfDaughterTPCfCls.value[0]) { - if ((track.tpcInnerParam() < ConfDaughterPTPCThr.value[0] && std::abs(o2::aod::pidutils::tpcNSigma(ConfDaughterPIDspecies.value[0], track)) <= ConfDaughterPIDnSigmaMax.value[0]) || - (track.tpcInnerParam() >= ConfDaughterPTPCThr.value[0] && std::abs(std::sqrt(o2::aod::pidutils::tpcNSigma(ConfDaughterPIDspecies.value[0], track) * o2::aod::pidutils::tpcNSigma(ConfDaughterPIDspecies.value[0], track) + o2::aod::pidutils::tofNSigma(ConfDaughterPIDspecies.value[0], track) * o2::aod::pidutils::tofNSigma(ConfDaughterPIDspecies.value[0], track))) <= ConfDaughterPIDnSigmaMax.value[0])) { - Daughter1.push_back(track); - ResoRegistry.fill(HIST("AnalysisQA/Reso/Daughter1/Pt"), track.pt()); - ResoRegistry.fill(HIST("AnalysisQA/Reso/Daughter1/Eta"), track.eta()); - ResoRegistry.fill(HIST("AnalysisQA/Reso/Daughter1/Phi"), track.phi()); - } - } - // select daugher 2 - if (track.sign() == ConfDaughterCharge.value[1] && track.pt() <= ConfDaughterPtUp.value[1] && track.pt() >= ConfDaughterPtLow.value[1] && std::abs(track.eta()) <= ConfDaughterEta.value[1] && std::abs(track.dcaXY()) <= ConfDaughterDCAxy.value[1] && std::abs(track.dcaZ()) <= ConfDaughterDCAz.value[1] && track.tpcNClsCrossedRows() >= ConfDaughterNCrossed.value[1] && track.tpcNClsFound() >= ConfDaughterNClus.value[1] && track.tpcCrossedRowsOverFindableCls() >= ConfDaughterTPCfCls.value[1]) { - if ((track.tpcInnerParam() < ConfDaughterPTPCThr.value[1] && std::abs(o2::aod::pidutils::tpcNSigma(ConfDaughterPIDspecies.value[1], track)) <= ConfDaughterPIDnSigmaMax.value[1]) || - (track.tpcInnerParam() >= ConfDaughterPTPCThr.value[1] && std::abs(std::sqrt(o2::aod::pidutils::tpcNSigma(ConfDaughterPIDspecies.value[1], track) * o2::aod::pidutils::tpcNSigma(ConfDaughterPIDspecies.value[1], track) + o2::aod::pidutils::tofNSigma(ConfDaughterPIDspecies.value[1], track) * o2::aod::pidutils::tofNSigma(ConfDaughterPIDspecies.value[1], track))) <= ConfDaughterPIDnSigmaMax.value[1])) { - Daughter2.push_back(track); - ResoRegistry.fill(HIST("AnalysisQA/Reso/Daughter2/Pt"), track.pt()); - ResoRegistry.fill(HIST("AnalysisQA/Reso/Daughter2/Eta"), track.eta()); - ResoRegistry.fill(HIST("AnalysisQA/Reso/Daughter2/Phi"), track.phi()); - } - } - } - } - - if (ConfIsActivateV0.value) { - for (auto& v0 : fullV0s) { - - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); - ///\tocheck funnily enough if we apply the filter the - /// sign of Pos and Neg track is always negative - // const auto dcaXYpos = postrack.dcaXY(); - // const auto dcaZpos = postrack.dcaZ(); - // const auto dcapos = std::sqrt(pow(dcaXYpos, 2.) + pow(dcaZpos, 2.)); - v0Cuts.fillLambdaQA(col, v0, postrack, negtrack); - - if (!v0Cuts.isSelectedMinimal(col, v0, postrack, negtrack)) { - continue; - } - - // if (ConfRejectITSHitandTOFMissing) { - // Uncomment only when TOF timing is solved - // bool itsHit = o2PhysicsTrackSelection->IsSelected(postrack, - // TrackSelection::TrackCuts::kITSHits); bool itsHit = - // o2PhysicsTrackSelection->IsSelected(negtrack, - // TrackSelection::TrackCuts::kITSHits); - // } - - v0Cuts.fillQA(col, v0, postrack, negtrack); ///\todo fill QA also for daughters - auto cutContainerV0 = v0Cuts.getCutContainer(col, v0, postrack, negtrack); - - int postrackID = v0.posTrackId(); - int rowInPrimaryTrackTablePos = -1; - rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); - childIDs[0] = rowInPrimaryTrackTablePos; - childIDs[1] = 0; - outputParts(outputCollision.lastIndex(), - v0.positivept(), v0.positiveeta(), v0.positivephi(), - aod::femtodreamparticle::ParticleType::kV0Child, - cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kPosCuts), - cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kPosPID), - postrack.dcaXY(), - childIDs, - 0, - 0); - const int rowOfPosTrack = outputParts.lastIndex(); - if constexpr (isMC) { - fillMCParticle(col, postrack, o2::aod::femtodreamparticle::ParticleType::kV0Child); - } - int negtrackID = v0.negTrackId(); - int rowInPrimaryTrackTableNeg = -1; - rowInPrimaryTrackTableNeg = getRowDaughters(negtrackID, tmpIDtrack); - childIDs[0] = 0; - childIDs[1] = rowInPrimaryTrackTableNeg; - outputParts(outputCollision.lastIndex(), - v0.negativept(), - v0.negativeeta(), - v0.negativephi(), - aod::femtodreamparticle::ParticleType::kV0Child, - cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kNegCuts), - cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kNegPID), - negtrack.dcaXY(), - childIDs, - 0, - 0); - const int rowOfNegTrack = outputParts.lastIndex(); - if constexpr (isMC) { - fillMCParticle(col, negtrack, o2::aod::femtodreamparticle::ParticleType::kV0Child); - } - std::vector indexChildID = {rowOfPosTrack, rowOfNegTrack}; - outputParts(outputCollision.lastIndex(), - v0.pt(), - v0.eta(), - v0.phi(), - aod::femtodreamparticle::ParticleType::kV0, - cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kV0), - 0, - v0.v0cosPA(), - indexChildID, - v0.mLambda(), - v0.mAntiLambda()); - if (ConfIsDebug.value) { - fillDebugParticle(postrack); // QA for positive daughter - fillDebugParticle(negtrack); // QA for negative daughter - fillDebugParticle(v0); // QA for v0 - } - if constexpr (isMC) { - fillMCParticle(col, v0, o2::aod::femtodreamparticle::ParticleType::kV0); - } - } - } - if (ConfIsActivateCascade.value) { - for (auto& casc : fullCascades) { - // get the daughter tracks - const auto& posTrackCasc = casc.template posTrack_as(); - const auto& negTrackCasc = casc.template negTrack_as(); - const auto& bachTrackCasc = casc.template bachelor_as(); - - cascadeCuts.fillQA<0, aod::femtodreamparticle::ParticleType::kCascade>(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc); - if (!cascadeCuts.isSelectedMinimal(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc)) { - continue; - } - cascadeCuts.fillQA<1, aod::femtodreamparticle::ParticleType::kCascade>(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc); - - // auto cutContainerCasc = cascadeCuts.getCutContainer(col, casc, v0daugh, posTrackCasc, negTrackCasc, bachTrackCasc); - auto cutContainerCasc = cascadeCuts.getCutContainer(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc); - - // Fill positive child - int poscasctrackID = casc.posTrackId(); - int rowInPrimaryTrackTablePosCasc = -1; - rowInPrimaryTrackTablePosCasc = getRowDaughters(poscasctrackID, tmpIDtrack); - cascadechildIDs[0] = rowInPrimaryTrackTablePosCasc; - cascadechildIDs[1] = 0; - cascadechildIDs[2] = 0; - outputParts(outputCollision.lastIndex(), - posTrackCasc.pt(), - posTrackCasc.eta(), - posTrackCasc.phi(), - aod::femtodreamparticle::ParticleType::kCascadeV0Child, - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kPosCuts), - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kPosPID), - posTrackCasc.dcaXY(), - cascadechildIDs, - 0, - 0); - const int rowOfPosCascadeTrack = outputParts.lastIndex(); - // TODO: include here MC filling - //------ - - // Fill negative child - int negcasctrackID = casc.negTrackId(); - int rowInPrimaryTrackTableNegCasc = -1; - rowInPrimaryTrackTableNegCasc = getRowDaughters(negcasctrackID, tmpIDtrack); - cascadechildIDs[0] = 0; - cascadechildIDs[1] = rowInPrimaryTrackTableNegCasc; - cascadechildIDs[2] = 0; - outputParts(outputCollision.lastIndex(), - negTrackCasc.pt(), - negTrackCasc.eta(), - negTrackCasc.phi(), - aod::femtodreamparticle::ParticleType::kCascadeV0Child, - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kNegCuts), - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kNegPID), - negTrackCasc.dcaXY(), - cascadechildIDs, - 0, - 0); - const int rowOfNegCascadeTrack = outputParts.lastIndex(); - // TODO: include here MC filling - //------ - - // Fill bachelor child - int bachelorcasctrackID = casc.bachelorId(); - int rowInPrimaryTrackTableBachelorCasc = -1; - rowInPrimaryTrackTableBachelorCasc = getRowDaughters(bachelorcasctrackID, tmpIDtrack); - cascadechildIDs[0] = 0; - cascadechildIDs[1] = 0; - cascadechildIDs[2] = rowInPrimaryTrackTableBachelorCasc; - outputParts(outputCollision.lastIndex(), - bachTrackCasc.pt(), - bachTrackCasc.eta(), - bachTrackCasc.phi(), - aod::femtodreamparticle::ParticleType::kCascadeBachelor, - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kBachCuts), - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kBachPID), - bachTrackCasc.dcaXY(), - cascadechildIDs, - 0, - 0); - const int rowOfBachelorCascadeTrack = outputParts.lastIndex(); - // TODO: include here MC filling - //------ - - // Fill cascades - std::vector indexCascadeChildID = {rowOfPosCascadeTrack, rowOfNegCascadeTrack, rowOfBachelorCascadeTrack}; - outputParts(outputCollision.lastIndex(), - casc.pt(), - casc.eta(), - casc.phi(), - aod::femtodreamparticle::ParticleType::kCascade, - cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kCascade), - 0, - casc.casccosPA(col.posX(), col.posY(), col.posZ()), - indexCascadeChildID, - casc.mXi(), - casc.mLambda()); - // TODO: include here MC filling - //------ - - if (ConfIsDebug.value) { - fillDebugParticle(posTrackCasc); // QA for positive daughter - fillDebugParticle(negTrackCasc); // QA for negative daughter - fillDebugParticle(bachTrackCasc); // QA for negative daughter - fillDebugCascade(casc, col); // QA for Cascade - } - } - } - - if (ConfIsActivateReso.value) { - for (std::size_t iDaug1 = 0; iDaug1 < Daughter1.size(); ++iDaug1) { - for (std::size_t iDaug2 = 0; iDaug2 < Daughter2.size(); ++iDaug2) { - // MC stuff is still missing, also V0 QA - // ALSO: fix indices and other table entries which are now set to 0 as deflaut as not needed for p-p-phi cf ana - - ROOT::Math::PtEtaPhiMVector tempD1(Daughter1.at(iDaug1).pt(), Daughter1.at(iDaug1).eta(), Daughter1.at(iDaug1).phi(), ConfDaug1Daugh2ResoMass.value[0]); - ROOT::Math::PtEtaPhiMVector tempD2(Daughter2.at(iDaug2).pt(), Daughter2.at(iDaug2).eta(), Daughter2.at(iDaug2).phi(), ConfDaug1Daugh2ResoMass.value[1]); - - ROOT::Math::PtEtaPhiMVector tempPhi = tempD1 + tempD2; - - ResoRegistry.fill(HIST("AnalysisQA/Reso/InvMass"), tempPhi.M()); - - if ((tempPhi.M() >= ConfResoInvMassLowLimit.value) && (tempPhi.M() <= ConfResoInvMassUpLimit.value)) { - - ResoRegistry.fill(HIST("AnalysisQA/Reso/InvMass_selected"), tempPhi.M()); - ResoRegistry.fill(HIST("AnalysisQA/Reso/PtD1_selected"), Daughter1.at(iDaug1).pt()); - ResoRegistry.fill(HIST("AnalysisQA/Reso/PtD2_selected"), Daughter2.at(iDaug2).pt()); - - childIDs[0] = 0; - childIDs[1] = 0; - std::vector indexChildID = {0, 0}; - outputParts(outputCollision.lastIndex(), - static_cast(Daughter1.at(iDaug1).pt()), static_cast(Daughter1.at(iDaug1).eta()), static_cast(Daughter1.at(iDaug1).phi()), - aod::femtodreamparticle::ParticleType::kV0Child, - static_cast(0), - static_cast(0), - static_cast(Daughter1.at(iDaug1).dcaXY()), - childIDs, - 0, - 0); - outputParts(outputCollision.lastIndex(), - static_cast(Daughter2.at(iDaug2).pt()), static_cast(Daughter2.at(iDaug2).eta()), static_cast(Daughter2.at(iDaug2).phi()), - aod::femtodreamparticle::ParticleType::kV0Child, - static_cast(0), - static_cast(0), - static_cast(Daughter2.at(iDaug2).dcaXY()), - childIDs, - 0, - 0); - outputParts(outputCollision.lastIndex(), - static_cast(tempPhi.pt()), - static_cast(tempPhi.eta()), - static_cast(tempPhi.phi()), - aod::femtodreamparticle::ParticleType::kV0, - static_cast(0), - 0, - 0.f, - indexChildID, - tempPhi.M(), - tempPhi.M()); - if (ConfIsDebug.value) { - fillDebugParticle(Daughter1.at(iDaug1)); // QA for positive daughter - fillDebugParticle(Daughter2.at(iDaug2)); // QA for negative daughter - outputDebugParts(-999., // sign - -999., -999., -999., -999., -999., -999., -999., -999., -999., // track properties (DCA, NCls, crossed rows, etc.) - -999., -999., -999., -999., -999., -999., -999., -999., // TPC PID (TPC signal + particle hypothesis) - -999., -999., -999., -999., -999., -999., -999., // TOF PID - -999., -999., -999., -999., -999., -999., -999., -999., // ITS PID - -999., -999., -999., -999., -999., -999., // V0 properties - -999., -999., -999., -999., -999., -999., -999.); // Cascade properties - } - } - } - } - } - } - - void - processData(aod::FemtoFullCollision const& col, - aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s, - o2::aod::V0sLinked const&, - o2::aod::CascDatas const& fullCascades) - { - // get magnetic field for run - initCCDB_Mag_Trig(col.bc_as()); - // fill the tables - auto tracksWithItsPid = soa::Attach(tracks); - if (ConfUseItsPid.value) { - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracksWithItsPid, fullV0s, fullCascades); - } else { - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); - } - } - PROCESS_SWITCH(femtoDreamProducerTaskWithCascades, processData, - "Provide experimental data", true); - - void - processData_noCentrality(aod::FemtoFullCollision_noCent const& col, - aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s, - o2::aod::V0sLinked const&, - o2::aod::CascDatas const& fullCascades) - { - // get magnetic field for run - initCCDB_Mag_Trig(col.bc_as()); - // fill the tables - auto tracksWithItsPid = soa::Attach(tracks); - if (ConfUseItsPid.value) { - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracksWithItsPid, fullV0s, fullCascades); - } else { - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); - } - } - PROCESS_SWITCH(femtoDreamProducerTaskWithCascades, processData_noCentrality, - "Provide experimental data without centrality information", false); - - void processData_CentPbPb(aod::FemtoFullCollision_CentPbPb const& col, - aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s, - o2::aod::CascDatas const& fullCascades) - { - // get magnetic field for run - initCCDB_Mag_Trig(col.bc_as()); - // fill the tables - auto tracksWithItsPid = soa::Attach(tracks); - if (ConfUseItsPid.value) { - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracksWithItsPid, fullV0s, fullCascades); - } else { - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); - } - } - PROCESS_SWITCH(femtoDreamProducerTaskWithCascades, processData_CentPbPb, - "Provide experimental data with centrality information for PbPb collisions", false); - - void processMC(aod::FemtoFullCollisionMC const& col, - aod::BCsWithTimestamps const&, - soa::Join const& tracks, - aod::FemtoFullMCgenCollisions const&, - aod::McParticles const&, - soa::Join const& fullV0s, /// \todo with FilteredFullV0s - soa::Join const& fullCascades) - { - // get magnetic field for run - initCCDB_Mag_Trig(col.bc_as()); - // fill the tables - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); - } - PROCESS_SWITCH(femtoDreamProducerTaskWithCascades, processMC, "Provide MC data", false); - - void processMC_noCentrality(aod::FemtoFullCollision_noCent_MC const& col, - aod::BCsWithTimestamps const&, - soa::Join const& tracks, - aod::FemtoFullMCgenCollisions const&, - aod::McParticles const&, - soa::Join const& fullV0s, /// \todo with FilteredFullV0s - soa::Join const& fullCascades) - { - // get magnetic field for run - initCCDB_Mag_Trig(col.bc_as()); - // fill the tables - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); - } - PROCESS_SWITCH(femtoDreamProducerTaskWithCascades, processMC_noCentrality, "Provide MC data without requiring a centrality calibration", false); - - void processMC_CentPbPb(aod::FemtoFullCollisionMC_CentPbPb const& col, - aod::BCsWithTimestamps const&, - soa::Join const& tracks, - aod::FemtoFullMCgenCollisions const&, - aod::McParticles const&, - soa::Join const& fullV0s, /// \todo with FilteredFullV0s - soa::Join const& fullCascades) - { - // get magnetic field for run - initCCDB_Mag_Trig(col.bc_as()); - // fill the tables - fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); - } - PROCESS_SWITCH(femtoDreamProducerTaskWithCascades, processMC_CentPbPb, "Provide MC data with centrality information for PbPb collisions", false); -}; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx index 9f080fd2dd0..6f45f0c2672 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx @@ -76,9 +76,10 @@ struct femtoDreamPairTaskTrackTrack { Configurable MultMax{"MultMax", 99999, "Maximum Multiplicity (MultNtr)"}; Configurable MultPercentileMin{"MultPercentileMin", 0, "Maximum Multiplicity Percentile"}; Configurable MultPercentileMax{"MultPercentileMax", 100, "Minimum Multiplicity Percentile"}; + Configurable SphericityMin{"SphericityMin", 0, "Minimum event sphericity"}; } EventSel; - Filter EventMultiplicity = aod::femtodreamcollision::multNtr >= EventSel.MultMin && aod::femtodreamcollision::multNtr <= EventSel.MultMax; + Filter EventMultiplicity = aod::femtodreamcollision::multNtr >= EventSel.MultMin && aod::femtodreamcollision::multNtr <= EventSel.MultMax && aod::femtodreamcollision::sphericity >= EventSel.SphericityMin; Filter EventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= EventSel.MultPercentileMin && aod::femtodreamcollision::multV0M <= EventSel.MultPercentileMax; using FilteredCollisions = soa::Filtered; diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index d4cdefecf3b..37a16abc46b 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -28,6 +28,7 @@ #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/CCDB/ctpRateFetcher.h" @@ -472,6 +473,31 @@ struct FemtoUniverseProducerTask { return mask; } + template + using hasStrangeTOF = decltype(std::declval().tofNSigmaXiLaPi()); + + /// bitmask to save strangeness TOF for cascade analysis + template + aod::femtouniverseparticle::CutContainerType PIDStrangeTOFBitmask(const CascType& casc) + { + aod::femtouniverseparticle::CutContainerType mask = 0u; + if constexpr (std::experimental::is_detected::value) { + if (casc.tofNSigmaXiLaPi() < ConfPIDBitmask.confNsigmaTOFParticleChild) + mask |= (1u); + if (casc.tofNSigmaXiLaPr() < ConfPIDBitmask.confNsigmaTOFParticleChild) + mask |= (2u); + if (casc.tofNSigmaXiPi() < ConfPIDBitmask.confNsigmaTOFParticleChild) + mask |= (4u); + if (casc.tofNSigmaOmLaPi() < ConfPIDBitmask.confNsigmaTOFParticleChild) + mask |= (8u); + if (casc.tofNSigmaOmLaPr() < ConfPIDBitmask.confNsigmaTOFParticleChild) + mask |= (16u); + if (casc.tofNSigmaOmKa() < ConfPIDBitmask.confNsigmaTOFParticleChild) + mask |= (32u); + } + return mask; + } + Zorro zorro; OutputObj zorroSummary{"zorroSummary"}; int mRunNumberZorro = 0; @@ -683,7 +709,7 @@ struct FemtoUniverseProducerTask { mRunNumber = bc.runNumber(); } - template + template void fillDebugParticle(ParticleType const& particle) { if constexpr (isTrackOrV0) { @@ -706,13 +732,15 @@ struct FemtoUniverseProducerTask { -999., -999., -999., -999., -999., -999.); // QA for phi or D0/D0bar children - } else if constexpr (isXi) { - outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., - particle.dcacascdaughters(), particle.cascradius(), - particle.x(), particle.y(), particle.z(), - particle.mOmega()); // QA for Xi Cascades (later do the same for Omegas) + } else if constexpr (isCasc) { + if constexpr (std::experimental::is_detected::value) { + outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999., -999., particle.tofNSigmaXiLaPi(), + particle.tofNSigmaXiLaPr(), particle.tofNSigmaXiPi(), particle.tofNSigmaOmLaPi(), + particle.tofNSigmaOmLaPr(), particle.tofNSigmaOmKa(), + particle.dcacascdaughters(), particle.cascradius(), + particle.x(), particle.y(), particle.z(), -999.); + } } else { // LOGF(info, "isTrack0orV0: %d, isPhi: %d", isTrackOrV0, isPhiOrD0); outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., @@ -1246,8 +1274,8 @@ struct FemtoUniverseProducerTask { casc.positiveeta(), casc.positivephi(), aod::femtouniverseparticle::ParticleType::kV0Child, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosCuts), - PIDBitmask(posTrackCasc), // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosPID), + 0, + PIDBitmask(posTrackCasc), hasTOF, childIDs, 0, @@ -1268,8 +1296,8 @@ struct FemtoUniverseProducerTask { casc.negativeeta(), casc.negativephi(), aod::femtouniverseparticle::ParticleType::kV0Child, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), - PIDBitmask(negTrackCasc), // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), + 0, + PIDBitmask(negTrackCasc), hasTOF, childIDs, 0, @@ -1291,8 +1319,8 @@ struct FemtoUniverseProducerTask { casc.bacheloreta(), casc.bachelorphi(), aod::femtouniverseparticle::ParticleType::kCascadeBachelor, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), - PIDBitmask(bachTrackCasc), // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), + 0, + PIDBitmask(bachTrackCasc), hasTOF, childIDs, 0, @@ -1308,8 +1336,8 @@ struct FemtoUniverseProducerTask { casc.eta(), casc.phi(), aod::femtouniverseparticle::ParticleType::kCascade, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kV0), 0, + PIDStrangeTOFBitmask(casc), 0, indexCascChildID, casc.mXi(), @@ -2112,7 +2140,7 @@ struct FemtoUniverseProducerTask { aod::BCsWithTimestamps const&, soa::Filtered const& tracks, o2::aod::V0Datas const& fullV0s, - o2::aod::CascDatas const& fullCascades) + soa::Join const& fullCascades) { getMagneticFieldTesla(col.bc_as()); const auto colcheck = fillCollisions(col, tracks); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index 8cad618d1dd..966c3ae0bac 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -57,8 +57,9 @@ struct femtoUniversePairTaskTrackCascadeExtended { Configurable confCascInvMassLowLimit{"confCascInvMassLowLimit", 1.315, "Lower limit of the Casc invariant mass"}; Configurable confCascInvMassUpLimit{"confCascInvMassUpLimit", 1.325, "Upper limit of the Casc invariant mass"}; - Configurable confNSigmaTPCPion{"confNSigmaTPCPion", 4, "NSigmaTPCPion"}; - Configurable confNSigmaTPCProton{"confNSigmaTPCProton", 4, "NSigmaTPCProton"}; + // TODO: Add seperate selection for daughter particles + // Configurable confNSigmaTPCPion{"confNSigmaTPCPion", 4, "NSigmaTPCPion"}; + // Configurable confNSigmaTPCProton{"confNSigmaTPCProton", 4, "NSigmaTPCProton"}; /// applying narrow cut Configurable confZVertexCut{"confZVertexCut", 10.f, "Event sel: Maximum z-Vertex (cm)"}; @@ -350,25 +351,12 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); - // nSigma selection for daughter and bachelor tracks - if (part.sign() < 0) { - if (std::abs(posChild.tpcNSigmaPr()) > confNSigmaTPCProton) { - continue; - } - if (std::abs(negChild.tpcNSigmaPi()) > confNSigmaTPCPion) { - continue; - } - } else { - if (std::abs(negChild.tpcNSigmaPr()) > confNSigmaTPCProton) { - continue; - } - if (std::abs(posChild.tpcNSigmaPi()) > confNSigmaTPCPion) { - continue; - } - } - if (std::abs(bachelor.tpcNSigmaPi()) > confNSigmaTPCPion) { + float posChildTPC, negChildTPC, bachelorTPC, posChildTOF, negChildTOF, bachelorTOF; + if (!isParticleTPC(posChild, CascChildTable[confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2], &bachelorTPC)) + continue; + + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[confCascType1][1], &negChildTOF))) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2], &bachelorTOF)) continue; - } rXiQA.fill(HIST("hPtXi"), part.pt()); rXiQA.fill(HIST("hEtaXi"), part.eta()); @@ -863,32 +851,31 @@ struct femtoUniversePairTaskTrackCascadeExtended { continue; cascQAHistos.fillQA(part); - - for (const auto& part : groupPartsOne) { - int pdgCode = static_cast(part.pidCut()); - if (pdgCode != confTrkPDGCodePartOne) - continue; - const auto& pdgTrackParticle = pdgMC->GetParticle(pdgCode); - if (!pdgTrackParticle) { - continue; - } - - if (pdgTrackParticle->Charge() > 0) { - trackHistoPartOnePos.fillQA(part); - } else if (pdgTrackParticle->Charge() < 0) { - trackHistoPartOneNeg.fillQA(part); - } + } + for (const auto& part : groupPartsOne) { + int pdgCode = static_cast(part.pidCut()); + if (pdgCode != confTrkPDGCodePartOne) + continue; + const auto& pdgTrackParticle = pdgMC->GetParticle(pdgCode); + if (!pdgTrackParticle) { + continue; } - for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (static_cast(p1.pidCut()) != confTrkPDGCodePartOne) - continue; - int pdgCodeCasc = static_cast(p2.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) - continue; - sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + if (pdgTrackParticle->Charge() > 0) { + trackHistoPartOnePos.fillQA(part); + } else if (pdgTrackParticle->Charge() < 0) { + trackHistoPartOneNeg.fillQA(part); } } + + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + if (static_cast(p1.pidCut()) != confTrkPDGCodePartOne) + continue; + int pdgCodeCasc = static_cast(p2.pidCut()); + if ((confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) + continue; + sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + } } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventMCgen, "Enable processing same event MC truth for track - cascade", false); @@ -907,24 +894,24 @@ struct femtoUniversePairTaskTrackCascadeExtended { continue; cascQAHistos.fillQA(part); + } - auto pairProcessFunc = [&](auto& p1, auto& p2) -> void { - int pdgCodeCasc1 = static_cast(p1.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) - return; - int pdgCodeCasc2 = static_cast(p2.pidCut()); - if ((confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) - return; - sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); - }; + auto pairProcessFunc = [&](auto& p1, auto& p2) -> void { + int pdgCodeCasc1 = static_cast(p1.pidCut()); + if ((confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) + return; + int pdgCodeCasc2 = static_cast(p2.pidCut()); + if ((confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) + return; + sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + }; - if (confCascType1 == confCascType2) { - for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsTwo, groupPartsTwo))) - pairProcessFunc(p1, p2); - } else { - for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsTwo, groupPartsTwo))) - pairProcessFunc(p1, p2); - } + if (confCascType1 == confCascType2) { + for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsTwo, groupPartsTwo))) + pairProcessFunc(p1, p2); + } else { + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsTwo, groupPartsTwo))) + pairProcessFunc(p1, p2); } } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventCascMCgen, "Enable processing same event MC truth for cascade - cascade", false); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index 3dfb7d7f4ed..2ea687a3ed6 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -68,6 +68,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { struct : o2::framework::ConfigurableGroup { Configurable ConfNsigmaCombined{"ConfNsigmaCombined", 3.0f, "TPC and TOF Pion Sigma (combined) for momentum > ConfTOFPtMin"}; Configurable ConfNsigmaTPC{"ConfNsigmaTPC", 3.0f, "TPC Pion Sigma for momentum < ConfTOFPtMin"}; + Configurable ConfIsElReject{"ConfIsElReject", false, "Is electron rejection activated"}; + Configurable ConfNsigmaTPCElReject{"ConfNsigmaTPCElReject", 2.0f, "TPC Electron Sigma for momentum < ConfTOFPtMin"}; Configurable ConfTOFPtMin{"ConfTOFPtMin", 0.5f, "Min. Pt for which TOF is required for PID."}; Configurable ConfEtaMax{"ConfEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; @@ -306,7 +308,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { } } - bool IsPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) + bool IsPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCElReject) { //|nsigma_TPC| < 3 for p < 0.5 GeV/c //|nsigma_combined| < 3 for p > 0.5 @@ -317,10 +319,18 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { // ConfNsigmaCombined -> TPC and TOF Pion Sigma (combined) for momentum > 0.5 if (true) { if (mom < twotracksconfigs.ConfTOFPtMin) { - if (std::abs(nsigmaTPCPi) < twotracksconfigs.ConfNsigmaTPC) { - return true; + if (twotracksconfigs.ConfIsElReject) { + if ((std::abs(nsigmaTPCPi) < twotracksconfigs.ConfNsigmaTPC) && (std::abs(nsigmaTPCElReject) > twotracksconfigs.ConfNsigmaTPCElReject)) { + return true; + } else { + return false; + } } else { - return false; + if ((std::abs(nsigmaTPCPi) < twotracksconfigs.ConfNsigmaTPC)) { + return true; + } else { + return false; + } } } else { if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < twotracksconfigs.ConfNsigmaCombined) { @@ -333,7 +343,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { return false; } - bool IsParticleNSigma(int8_t particle_number, float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) + bool IsParticleNSigma(int8_t particle_number, float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK, float nsigmaTPCElReject) { if (particle_number == 1) { switch (trackonefilter.ConfPDGCodePartOne) { @@ -343,7 +353,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { break; case 211: // Pion+ case -211: // Pion- - return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi, nsigmaTPCElReject); break; case 321: // Kaon+ case -321: // Kaon- @@ -361,7 +371,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { break; case 211: // Pion+ case -211: // Pion- - return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi, nsigmaTPCElReject); break; case 321: // Kaon+ case -321: // Kaon- @@ -468,7 +478,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// Histogramming same event if ((ContType == 1 || ContType == 2) && fillQA) { for (const auto& part : groupPartsOne) { - if (!IsParticleNSigma((int8_t)1, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)1, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Electron))) { continue; } trackHistoPartOne.fillQA(part); @@ -478,7 +488,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { if ((ContType == 1 || ContType == 3) && fillQA) { for (const auto& part : groupPartsTwo) { - if (!IsParticleNSigma((int8_t)2, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)2, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Electron))) { continue; } trackHistoPartTwo.fillQA(part); @@ -490,11 +500,11 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// Now build the combinations for non-identical particle pairs for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (!IsParticleNSigma((int8_t)1, p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)1, p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(p1, o2::track::PID::Electron))) { continue; } - if (!IsParticleNSigma((int8_t)2, p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)2, p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(p2, o2::track::PID::Electron))) { continue; } @@ -520,11 +530,11 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { } else { for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsOne))) { - if (!IsParticleNSigma((int8_t)2, p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)2, p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(p1, o2::track::PID::Electron))) { continue; } - if (!IsParticleNSigma((int8_t)2, p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)2, p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(p2, o2::track::PID::Electron))) { continue; } @@ -700,11 +710,11 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (!IsParticleNSigma((int8_t)2, p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)2, p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(p1, o2::track::PID::Electron))) { continue; } - if (!IsParticleNSigma((int8_t)2, p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon))) { + if (!IsParticleNSigma((int8_t)2, p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(p2, o2::track::PID::Electron))) { continue; } diff --git a/PWGCF/Flow/TableProducer/zdcQVectors.cxx b/PWGCF/Flow/TableProducer/zdcQVectors.cxx index c748b1f51ec..bf6dc06422c 100644 --- a/PWGCF/Flow/TableProducer/zdcQVectors.cxx +++ b/PWGCF/Flow/TableProducer/zdcQVectors.cxx @@ -220,6 +220,7 @@ struct ZdcQVectors { registry.add(Form("QA/before/hQ%s%s_vs_vx", coord, side), Form("hQ%s%s_vs_vx", coord, side), {HistType::kTProfile, {axisVx}}); registry.add(Form("QA/before/hQ%s%s_vs_vy", coord, side), Form("hQ%s%s_vs_vy", coord, side), {HistType::kTProfile, {axisVy}}); registry.add(Form("QA/before/hQ%s%s_vs_vz", coord, side), Form("hQ%s%s_vs_vz", coord, side), {HistType::kTProfile, {axisVz}}); + registry.add(Form("QA/Q%s%s_vs_iteration", coord, side), Form("hQ%s%s_vs_iteration", coord, side), {HistType::kTH2D, {{25, 0, 25}, axisQ}}); names[0].push_back(TString::Format("hQ%s%s_mean_Cent_V_run", coord, side)); names[1].push_back(TString::Format("hQ%s%s_mean_cent_run", coord, side)); @@ -444,8 +445,9 @@ struct ZdcQVectors { // iteration = 0 (Energy calibration) -> step 0 only // iteration 1,2,3,4,5 = recentering -> 5 steps per iteration (1x 4D + 4x 1D) - if (cal.calibfilesLoaded[cm]) + if (cal.calibfilesLoaded[cm]) { return; + } if (ccdb_dir.empty() == false) { cal.calibList[cm] = ccdb->getForTimeStamp(ccdb_dir, timestamp); @@ -548,7 +550,6 @@ struct ZdcQVectors { isSelected = true; - // TODO Implement other ZDC estimators auto cent = collision.centFT0C(); if (cfgFT0Cvariant1) cent = collision.centFT0CVariant1(); @@ -588,10 +589,16 @@ struct ZdcQVectors { runnumber = foundBC.runNumber(); // load new calibrations for new runs only - // UPLOAD Energy calibration and vmean in 1 histogram! if (runnumber != lastRunNumber) { + cal.calibfilesLoaded[0] = false; + cal.calibList[0] = nullptr; + + cal.calibfilesLoaded[1] = false; + cal.calibList[1] = nullptr; + cal.calibfilesLoaded[2] = false; cal.calibList[2] = nullptr; + lastRunNumber = runnumber; } @@ -844,6 +851,11 @@ struct ZdcQVectors { qRec[1] -= corrQyA[cor]; qRec[2] -= corrQxC[cor]; qRec[3] -= corrQyC[cor]; + + registry.get(HIST("QA/QXA_vs_iteration"))->Fill(cor, qRec[0]); + registry.get(HIST("QA/QYA_vs_iteration"))->Fill(cor, qRec[1]); + registry.get(HIST("QA/QXC_vs_iteration"))->Fill(cor, qRec[2]); + registry.get(HIST("QA/QYC_vs_iteration"))->Fill(cor, qRec[3]); } if (isSelected && cfgFillCommonRegistry) { diff --git a/PWGCF/Flow/Tasks/flowEseTask.cxx b/PWGCF/Flow/Tasks/flowEseTask.cxx index 6ab2155788a..74dc98bd528 100644 --- a/PWGCF/Flow/Tasks/flowEseTask.cxx +++ b/PWGCF/Flow/Tasks/flowEseTask.cxx @@ -125,7 +125,7 @@ struct FlowEseTask { Configurable cfgUSESP{"cfgUSESP", false, "cfg for sp"}; Configurable cfgPhiDepSig{"cfgPhiDepSig", 0.2, "cfg for significance on phi dependent study"}; - Configurable cfgShiftCorr{"cfgShiftCorr", false, "additional shift correction"}; + Configurable cfgShiftCorr{"cfgShiftCorr", true, "additional shift correction"}; Configurable cfgShiftCorrDef{"cfgShiftCorrDef", false, "additional shift correction definition"}; Configurable cfgShiftPath{"cfgShiftPath", "Users/j/junlee/Qvector/QvecCalib/Shift", "Path for Shift"}; @@ -150,6 +150,7 @@ struct FlowEseTask { ConfigurableAxis lowerQAxis{"lowerQAxis", {800, 0, 800}, "result of q2"}; ConfigurableAxis multNumAxis{"multNumAxis", {300, 0, 2700}, "mult num"}; ConfigurableAxis qvecAxis{"qvecAxis", {300, -1, 1}, "range of Qvector"}; + ConfigurableAxis qvec2Axis{"qvec2Axis", {600, 0, 600}, "range of Qvector Module"}; static constexpr float kMinAmplitudeThreshold = 1e-5f; static constexpr int kShiftLevel = 10; @@ -157,8 +158,11 @@ struct FlowEseTask { static constexpr std::array kCorrLevel = {2, 3, 4, 1}; static constexpr std::array kCentBoundaries = {0.0f, 3.49f, 4.93f, 6.98f, 8.55f, 9.87f, 11.0f, 12.1f, 13.1f, 14.0f}; static constexpr std::array kCentValues = {2.5f, 7.5f, 15.0f, 25.0f, 35.0f, 45.0f, 55.0f, 65.0f, 75.0f}; + static constexpr std::array kCentrality = {0, 10, 20, 30, 40, 50, 60, 70, 80}; + static constexpr std::array, 8> kLowQvec = {{{121, 196}, {110, 172}, {93, 143}, {74, 117}, {58, 92}, {43, 70}, {31, 50}, {21, 34}}}; static constexpr float kEtaAcceptance = 0.8f; static constexpr float kCentUpperLimit = 80.0f; + static constexpr int kCentNum = 8; TF1* fMultPVCutLow = nullptr; TF1* fMultPVCutHigh = nullptr; @@ -228,6 +232,12 @@ struct FlowEseTask { histos.add(Form("psi%d/h_alambda_cos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); histos.add(Form("psi%d/h_lambda_cos2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); histos.add(Form("psi%d/h_alambda_cos2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); + histos.add(Form("psi%d/h_lambda_cos2_q2", i), "", {HistType::kTH3F, {centAxis, qvec2Axis, cosAxis}}); + histos.add(Form("psi%d/h_alambda_cos2_q2", i), "", {HistType::kTH3F, {centAxis, qvec2Axis, cosAxis}}); + + histos.add(Form("psi%d/h_lambda_cos2_left", i), "", {HistType::kTH2F, {centAxis, cosAxis}}); + histos.add(Form("psi%d/h_lambda_cos2_mid", i), "", {HistType::kTH2F, {centAxis, cosAxis}}); + histos.add(Form("psi%d/h_lambda_cos2_right", i), "", {HistType::kTH2F, {centAxis, cosAxis}}); if (cfgRapidityDep) { histos.add(Form("psi%d/h_lambda_cos2_rap", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, rapAxis}}); @@ -236,6 +246,14 @@ struct FlowEseTask { histos.add(Form("psi%d/h_lambda_cossin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); histos.add(Form("psi%d/h_alambda_cossin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_lambda_cossin_left", i), "", {HistType::kTH2F, {centAxis, cosAxis}}); + histos.add(Form("psi%d/h_lambda_cossin_mid", i), "", {HistType::kTH2F, {centAxis, cosAxis}}); + histos.add(Form("psi%d/h_lambda_cossin_right", i), "", {HistType::kTH2F, {centAxis, cosAxis}}); + + histos.add(Form("psi%d/h_lambda_cossin_q2", i), "", {HistType::kTH3F, {centAxis, qvec2Axis, cosAxis}}); + histos.add(Form("psi%d/h_alambda_cossin_q2", i), "", {HistType::kTH3F, {centAxis, qvec2Axis, cosAxis}}); + histos.add(Form("psi%d/h_lambda_cossin_cov", i), "", {HistType::kTHnSparseF, {ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_alambda_cossin_cov", i), "", {HistType::kTHnSparseF, {ptAxis, cosAxis, centAxis}}); if (cfgAccAzimuth) { histos.add(Form("psi%d/h_lambda_coscos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); @@ -351,6 +369,9 @@ struct FlowEseTask { histos.add(Form("psi%d/QA/EPRes_FT0C_FT0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); histos.add(Form("psi%d/QA/EPRes_FT0C_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); histos.add(Form("psi%d/QA/EPRes_FT0A_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + + histos.add(Form("psi%d/QA/EPRes_RefARefB_cov", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + histos.add(Form("psi%d/QA/EPRes_RefARefBRefC_cov", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); } } @@ -617,6 +638,9 @@ struct FlowEseTask { histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A))); histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A))); histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A))); + + histos.fill(HIST("psi2/QA/EPRes_RefARefB_cov"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A)) * std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A))); + histos.fill(HIST("psi2/QA/EPRes_RefARefBRefC_cov"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A)) * std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A)) * std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A))); } else if (nmode == kCorrLevel[1]) { histos.fill(HIST("psi3/QA/EP_FT0C_shifted"), centrality, psidefFT0C + deltapsiFT0C); histos.fill(HIST("psi3/QA/EP_FT0A_shifted"), centrality, psidefFT0A + deltapsiFT0A); @@ -644,10 +668,6 @@ struct FlowEseTask { qvecRefAInd = refAId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; qvecRefBInd = refBId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; - histos.fill(HIST("histQvecCent"), std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), collision.centFT0C()); - histos.fill(HIST("histQvecV2"), collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], collision.centFT0C()); - histos.fill(HIST("histMult_Cent"), collision.sumAmplFT0C(), collision.centFT0C()); - for (const auto& v0 : V0s) { auto postrack = v0.template posTrack_as(); auto negtrack = v0.template negTrack_as(); @@ -752,12 +772,36 @@ struct FlowEseTask { if (nmode == kCorrLevel[0]) { //////////// if (lambdaTag) { + double q2 = std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()); histos.fill(HIST("psi2/h_lambda_cos"), v0.mLambda(), v0.pt(), angle * weight, centrality, relphi); histos.fill(HIST("psi2/h_lambda_cos2"), v0.mLambda(), v0.pt(), angle * angle, centrality, relphi); histos.fill(HIST("psi2/h_lambda_cossin"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); histos.fill(HIST("psi2/h_lambda_vncos"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); histos.fill(HIST("psi2/h_lambda_vnsin"), v0.mLambda(), v0.pt(), std::sin(relphi), centrality); + histos.fill(HIST("psi2/h_lambda_cos2_q2"), centrality, std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), angle * angle); + histos.fill(HIST("psi2/h_lambda_cossin_q2"), centrality, std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), angle * std::sin(relphi) * weight); + + histos.fill(HIST("psi2/h_lambda_cossin_cov"), v0.pt(), angle * angle * angle * std::sin(relphi) * weight, centrality); + + histos.fill(HIST("histQvecCent"), std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), centrality); + histos.fill(HIST("histQvecV2"), collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], collision.centFT0C()); + histos.fill(HIST("histMult_Cent"), collision.sumAmplFT0C(), collision.centFT0C()); + + for (int i = 0; i < kCentNum; i++) { + if (centrality >= kCentrality[i] && centrality < kCentrality[i + 1]) { + if (q2 < kLowQvec[i][0]) { + histos.fill(HIST("psi2/h_lambda_cos2_left"), centrality, angle * angle); + histos.fill(HIST("psi2/h_lambda_cossin_left"), centrality, angle * std::sin(relphi) * weight); + } else if (q2 >= kLowQvec[i][1]) { + histos.fill(HIST("psi2/h_lambda_cos2_right"), centrality, angle * angle); + histos.fill(HIST("psi2/h_lambda_cossin_right"), centrality, angle * std::sin(relphi) * weight); + } else { + histos.fill(HIST("psi2/h_lambda_cos2_mid"), centrality, angle * angle); + histos.fill(HIST("psi2/h_lambda_cossin_mid"), centrality, angle * std::sin(relphi) * weight); + } + } + } if (cfgRapidityDep) { histos.fill(HIST("psi2/h_lambda_cos2_rap"), v0.mLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); } @@ -807,6 +851,10 @@ struct FlowEseTask { histos.fill(HIST("psi2/h_alambda_vncos"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); histos.fill(HIST("psi2/h_alambda_vnsin"), v0.mAntiLambda(), v0.pt(), std::sin(relphi), centrality); + histos.fill(HIST("psi2/h_alambda_cos2_q2"), centrality, std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), angle * angle); + histos.fill(HIST("psi2/h_alambda_cossin_q2"), centrality, std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), angle * std::sin(relphi) * weight); + + histos.fill(HIST("psi2/h_alambda_cossin_cov"), v0.pt(), angle * angle * angle * std::sin(relphi) * weight, centrality); if (cfgRapidityDep) { histos.fill(HIST("psi2/h_alambda_cos2_rap"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); } diff --git a/PWGCF/Flow/Tasks/flowMc.cxx b/PWGCF/Flow/Tasks/flowMc.cxx index 5884fa0e127..d804840870d 100644 --- a/PWGCF/Flow/Tasks/flowMc.cxx +++ b/PWGCF/Flow/Tasks/flowMc.cxx @@ -87,6 +87,7 @@ struct FlowMc { O2_DEFINE_CONFIGURABLE(cfgRecoEvSel8, bool, false, "require sel8 for reconstruction events") O2_DEFINE_CONFIGURABLE(cfgRecoEvkIsGoodITSLayersAll, bool, false, "require kIsGoodITSLayersAll for reconstruction events") O2_DEFINE_CONFIGURABLE(cfgRecoEvkNoSameBunchPileup, bool, false, "require kNoSameBunchPileup for reconstruction events") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "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") Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.6003720411, 0.6152630970, 0.6288860646, 0.6360694031, 0.6409494798, 0.6450540203, 0.6482117301, 0.6512592056, 0.6640008690, 0.6862631416, 0.7005738691, 0.7106567432, 0.7170728333}, "parameter 0 for track density efficiency correction"}; Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-1.007592e-05, -8.932635e-06, -9.114538e-06, -1.054818e-05, -1.220212e-05, -1.312304e-05, -1.376433e-05, -1.412813e-05, -1.289562e-05, -1.050065e-05, -8.635725e-06, -7.380821e-06, -6.201250e-06}, "parameter 1 for track density efficiency correction"}; float maxEta = 0.8; @@ -405,6 +406,11 @@ struct FlowMc { // cut time intervals with dead ITS staves return 0; } + if (cfgEvSelkIsGoodZvtxFT0vsPV && !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 + return 0; + } return 1; } diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index 1442509bba0..8727a7f9e8f 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -113,30 +113,33 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cfgHarmMixed1, int, 2, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); O2_DEFINE_CONFIGURABLE(cfgHarmMixed2, int, 3, "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_pass4/meanQQ/Default", "ccdb dir for average QQ values in 1% centrality bins"); + 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_pass4/Default", "ccdb dir for NUA corrections"); - O2_DEFINE_CONFIGURABLE(cfgCCDB_NUE, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass4/NUE/Default", "ccdb dir for NUE corrections"); + 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"); O2_DEFINE_CONFIGURABLE(cfgCCDBdir_centrality, std::string, "", "ccdb dir for Centrality corrections"); // Confogirable axis - ConfigurableAxis axisCentrality{"axisCentrality", {10, 0, 100}, "Centrality bins for vn "}; + 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{2389.99, -83.8483, 1.11062, -0.00672263, 1.54725e-05, 4067.4, -145.485, 2.27273, -0.0186308, 6.5501e-05}, "Multiplicity cuts (PV) first 5 parameters cutLOW last 5 cutHIGH (Default is +-3sigma pass4) "}; - Configurable> cfgEvSelsMult{"cfgEvSelsMult", std::vector{1048.48, -31.4568, 0.287794, -0.00046847, -3.5909e-06, 2610.98, -83.3983, 1.0893, -0.00735094, 2.26929e-05}, "Multiplicity cuts (Global) first 5 parameters cutLOW last 5 cutHIGH (Default is +-3sigma pass4) "}; + Configurable> cfgEvSelsMultPv{"cfgEvSelsMultPv", std::vector{2228.05, -75.5988, 0.976695, -0.00585275, 1.40738e-05, 3795.65, -136.988, 2.12393, -0.017028, 5.78679e-05}, "Multiplicity cuts (PV) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; + Configurable> cfgEvSelsMult{"cfgEvSelsMult", std::vector{1308.86, -41.9314, 0.488423, -0.00248178, 4.71554e-06, 2973.55, -103.092, 1.47673, -0.0106685, 3.29348e-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; - using UsedCollisions = soa::Filtered>; - using UsedTracks = soa::Filtered>; + using GeneralCollisions = soa::Join; + using UnfilteredTracks = soa::Join; + + using UsedTracks = soa::Filtered; + using ZDCCollisions = soa::Filtered>; // For MC Reco and Gen - using CCs = soa::Filtered>; + using CCs = soa::Filtered>; // without SPTableZDC using CC = CCs::iterator; - using TCs = soa::Join; - using FilteredTCs = soa::Filtered>; + using TCs = soa::Join; + using FilteredTCs = soa::Filtered; using TC = TCs::iterator; using MCs = soa::Filtered; @@ -174,8 +177,9 @@ struct FlowSP { OutputObj fWeightsNEG{GFWWeights("weights_negative")}; HistogramRegistry registry{"registry"}; + HistogramRegistry histos{"QAhistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; - // Event selection cuts - Alex + // Event selection cuts TF1* fPhiCutLow = nullptr; TF1* fPhiCutHigh = nullptr; TF1* fMultPVCutLow = nullptr; @@ -232,9 +236,9 @@ struct FlowSP { enum ParticleType { kUnidentified, - kPion, - kKaon, - kProton + kPions, + kKaons, + kProtons }; static constexpr std::string_view Charge[] = {"incl/", "pos/", "neg/"}; @@ -276,150 +280,167 @@ struct FlowSP { int ptbins = ptbinning.size() - 1; - registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_FilteredEvent + 1, "Filtered event"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kTVXinTRD + 1, "kTVXinTRD"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_MultCuts + 1, "Multiplicity cuts"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kkIsGoodITSLayersAll"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_isSelectedZDC + 1, "isSelected"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_CentCuts + 1, "Cenrality range"); - - registry.add("hTrackCount", "Number of Tracks; Cut; #Tracks Passed Cut", {HistType::kTH1D, {{nTrackSelections, 0, nTrackSelections}}}); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Eta + 1, "Eta"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Pt + 1, "Pt"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAxy + 1, "DCAxy"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAz + 1, "DCAz"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_GlobalTracks + 1, "GlobalTracks"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_NCls + 1, "nClusters TPC"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_FshCls + 1, "Frac. sh. Cls TPC"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_TPCBoundary + 1, "TPC Boundary"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ZeroCharge + 1, "Only charged"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ParticleWeights + 1, "Apply weights"); + histos.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_FilteredEvent + 1, "Filtered event"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kTVXinTRD + 1, "kTVXinTRD"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_MultCuts + 1, "Multiplicity cuts"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kkIsGoodITSLayersAll"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_isSelectedZDC + 1, "isSelected"); + histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_CentCuts + 1, "Cenrality range"); + + histos.add("hTrackCount", "Number of Tracks; Cut; #Tracks Passed Cut", {HistType::kTH1D, {{nTrackSelections, 0, nTrackSelections}}}); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Eta + 1, "Eta"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Pt + 1, "Pt"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAxy + 1, "DCAxy"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAz + 1, "DCAz"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_GlobalTracks + 1, "GlobalTracks"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_NCls + 1, "nClusters TPC"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_FshCls + 1, "Frac. sh. Cls TPC"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_TPCBoundary + 1, "TPC Boundary"); + 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 (cfguseNUA2D) { - registry.add("weights/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("weights/hPhi_Eta_vz_positive", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("weights/hPhi_Eta_vz_negative", "", kTH3D, {axisPhi, axisEta, axisVz}); - } else { - // define output objects - fWeights->setPtBins(ptbins, &ptbinning[0]); - fWeights->init(true, false); + 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}); - fWeightsPOS->setPtBins(ptbins, &ptbinning[0]); - fWeightsPOS->init(true, false); + // define output objects + fWeights->setPtBins(ptbins, &ptbinning[0]); + fWeights->init(true, false); - fWeightsNEG->setPtBins(ptbins, &ptbinning[0]); - fWeightsNEG->init(true, false); - } + fWeightsPOS->setPtBins(ptbins, &ptbinning[0]); + fWeightsPOS->init(true, false); + + fWeightsNEG->setPtBins(ptbins, &ptbinning[0]); + fWeightsNEG->init(true, false); } if (cfgFillEventQA) { - registry.add("QA/after/hCentFT0C", " ; Cent FT0C (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/hCentFT0M", "; Cent FT0M (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/hCentFV0A", "; Cent FV0A (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/hCentNGlobal", "; Cent NGlobal (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/globalTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisNch}}); - registry.add("QA/after/PVTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisMultpv}}); - registry.add("QA/after/globalTracks_PVTracks", "", {HistType::kTH2D, {axisMultpv, axisNch}}); - registry.add("QA/after/globalTracks_multT0A", "", {HistType::kTH2D, {axisT0a, axisNch}}); - registry.add("QA/after/globalTracks_multV0A", "", {HistType::kTH2D, {axisV0a, axisNch}}); - registry.add("QA/after/multV0A_multT0A", "", {HistType::kTH2D, {axisT0a, axisV0a}}); - registry.add("QA/after/multT0C_centT0C", "", {HistType::kTH2D, {axisCent, axisT0c}}); - registry.add("QA/after/CentFT0C_vs_CentFT0Cvariant1", " ; Cent FT0C (%); Cent FT0Cvariant1 (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - registry.add("QA/after/CentFT0C_vs_CentFT0M", " ; Cent FT0C (%); Cent FT0M (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - registry.add("QA/after/CentFT0C_vs_CentFV0A", " ; Cent FT0C (%); Cent FV0A (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - registry.add("QA/after/CentFT0C_vs_CentNGlobal", " ; Cent FT0C (%); Cent NGlobal (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + 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}}); + histos.add("QA/after/hCentNGlobal", "; Cent NGlobal (%); ", {HistType::kTH1D, {axisCent}}); + histos.add("QA/after/globalTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisNch}}); + histos.add("QA/after/PVTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisMultpv}}); + histos.add("QA/after/globalTracks_PVTracks", "", {HistType::kTH2D, {axisMultpv, axisNch}}); + histos.add("QA/after/globalTracks_multT0A", "", {HistType::kTH2D, {axisT0a, axisNch}}); + histos.add("QA/after/globalTracks_multV0A", "", {HistType::kTH2D, {axisV0a, axisNch}}); + histos.add("QA/after/multV0A_multT0A", "", {HistType::kTH2D, {axisT0a, axisV0a}}); + histos.add("QA/after/multT0C_centT0C", "", {HistType::kTH2D, {axisCent, axisT0c}}); + histos.add("QA/after/CentFT0C_vs_CentFT0Cvariant1", " ; Cent FT0C (%); Cent FT0Cvariant1 (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + histos.add("QA/after/CentFT0C_vs_CentFT0M", " ; Cent FT0C (%); Cent FT0M (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + 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) { + 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}}); + histos.add("QA/after/PsiA_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); + histos.add("QA/after/PsiC_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); + histos.add("QA/after/PsiFull_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); + histos.add("QA/after/PsiA_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); + histos.add("QA/after/PsiC_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); + histos.add("QA/after/PsiFull_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); + histos.add("QA/after/PsiA_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); + histos.add("QA/after/PsiC_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); + histos.add("QA/after/PsiFull_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); + } + + if (cfgFillQABefore) { + histos.addClone("QA/after/", "QA/before/"); + } } if (doprocessData || doprocessMCReco) { - // track QA for pos, neg, incl - if (cfgFillPIDQA) { - registry.add("hPIDcounts", "", kTH2D, {{{4, 0, 4}, axisPt}}); - registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(1, "UFO"); - registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(2, "Pion"); - registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(3, "Kaon"); - registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(4, "Proton"); - - registry.add("incl/QA/after/hdEdxTPC_pt", "", {HistType::kTH2D, {axisPt, axisdEdx}}); - registry.add("incl/QA/after/hBetaTOF_pt", "", {HistType::kTH2D, {axisPt, axisBeta}}); - registry.add("incl/pion/QA/after/hNsigmaTPC_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); - registry.add("incl/pion/QA/after/hNsigmaTOF_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); - - if (cfgFillTrackQA) { - registry.add("incl/pion/QA/after/hPt", "", kTH1D, {axisPt}); - registry.add("incl/pion/QA/after/hPhi", "", kTH1D, {axisPhi}); - registry.add("incl/pion/QA/after/hPhi_uncorrected", "", kTH1D, {axisPhi}); - registry.add("incl/pion/QA/after/hEta", "", kTH1D, {axisEta}); - registry.add("incl/pion/QA/after/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("incl/pion/QA/after/hPhi_Eta_vz_corrected", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("incl/pion/QA/after/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); - registry.add("incl/pion/QA/after/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); - registry.add("incl/pion/QA/after/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); - registry.add("incl/pion/QA/after/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); - registry.add("incl/pion/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); - } - if (cfgFillQABefore) - registry.addClone("incl/pion/QA/after/", "incl/pion/QA/before/"); - } if (cfgFillTrackQA) { - registry.add("QA/after/pt_phi", "", {HistType::kTH2D, {axisPt, axisPhiMod}}); - registry.add("incl/QA/after/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("incl/QA/after/hPhi_Eta_vz_corrected", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("incl/QA/after/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); - registry.add("incl/QA/after/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); - registry.add("incl/QA/after/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); - registry.add("incl/QA/after/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); - registry.add("incl/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); + 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}); + histos.add("incl/QA/after/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); + histos.add("incl/QA/after/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); + histos.add("incl/QA/after/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); + histos.add("incl/QA/after/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); + histos.add("incl/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); if (cfgTrackSelDoTrackQAvsCent) { - registry.add("incl/QA/after/hPt", "", kTH2D, {axisPt, axisCent}); - registry.add("incl/QA/after/hPt_forward", "", kTH2D, {axisPt, axisCent}); - registry.add("incl/QA/after/hPt_forward_uncorrected", "", kTH2D, {axisPt, axisCent}); - registry.add("incl/QA/after/hPt_backward", "", kTH2D, {axisPt, axisCent}); - registry.add("incl/QA/after/hPt_backward_uncorrected", "", kTH2D, {axisPt, axisCent}); - registry.add("incl/QA/after/hPhi", "", kTH2D, {axisPhi, axisCent}); - registry.add("incl/QA/after/hPhi_uncorrected", "", kTH2D, {axisPhi, axisCent}); - registry.add("incl/QA/after/hEta", "", kTH2D, {axisEta, axisCent}); - registry.add("incl/QA/after/hEta_uncorrected", "", kTH2D, {axisEta, axisCent}); + 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}); + histos.add("incl/QA/after/hPhi_Eta_uncorrected", "", kTH3D, {axisPhi, axisEta, axisCent}); } else { - registry.add("incl/QA/after/hPt", "", kTH1D, {axisPt}); - registry.add("incl/QA/after/hPt_forward", "", kTH1D, {axisPt}); - registry.add("incl/QA/after/hPt_forward_uncorrected", "", kTH1D, {axisPt}); - registry.add("incl/QA/after/hPt_backward", "", kTH1D, {axisPt}); - registry.add("incl/QA/after/hPt_backward_uncorrected", "", kTH1D, {axisPt}); - registry.add("incl/QA/after/hPhi", "", kTH1D, {axisPhi}); - registry.add("incl/QA/after/hPhi_uncorrected", "", kTH1D, {axisPhi}); - registry.add("incl/QA/after/hEta", "", kTH1D, {axisEta}); - registry.add("incl/QA/after/hEta_uncorrected", "", kTH1D, {axisEta}); + histos.add("incl/QA/after/hPhi_Eta_Pt", "", kTH3D, {axisPhi, axisEta, axisPt}); + histos.add("incl/QA/after/hPhi_Eta_Pt_corrected", "", kTH3D, {axisPhi, axisEta, axisPt}); } if (cfgFillQABefore) - registry.addClone("incl/QA/after/", "incl/QA/before/"); + histos.addClone("incl/QA/after/", "incl/QA/before/"); + } + + if (cfgFillPIDQA) { + histos.add("hPIDcounts", "", kTH2D, {{{4, 0, 4}, axisPt}}); + histos.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(1, "UFO"); + histos.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(2, "Pion"); + histos.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(3, "Kaon"); + histos.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(4, "Proton"); + + histos.add("incl/QA/after/hdEdxTPC_pt", "", {HistType::kTH2D, {axisPt, axisdEdx}}); + histos.add("incl/QA/after/hBetaTOF_pt", "", {HistType::kTH2D, {axisPt, axisBeta}}); + histos.add("incl/QA/before/hdEdxTPC_pt", "", {HistType::kTH2D, {axisPt, axisdEdx}}); + histos.add("incl/QA/before/hBetaTOF_pt", "", {HistType::kTH2D, {axisPt, axisBeta}}); + + histos.add("incl/pion/QA/after/hNsigmaTPC_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); + histos.add("incl/pion/QA/after/hNsigmaTOF_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); + + histos.add("incl/pion/QA/after/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); + histos.add("incl/pion/QA/after/hPhi_Eta_vz_corrected", "", kTH3D, {axisPhi, axisEta, axisVz}); + histos.add("incl/pion/QA/after/hPhi_Eta_Pt", "", kTH3D, {axisPhi, axisEta, axisPt}); + histos.add("incl/pion/QA/after/hPhi_Eta_Pt_corrected", "", kTH3D, {axisPhi, axisEta, axisPt}); + histos.add("incl/pion/QA/after/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); + histos.add("incl/pion/QA/after/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); + histos.add("incl/pion/QA/after/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); + 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) { + histos.addClone("incl/pion/QA/after/", "incl/pion/QA/before/"); + } + + histos.addClone("incl/pion/", "incl/kaon/"); + histos.addClone("incl/pion/", "incl/proton/"); } if (doprocessMCReco) { - registry.add("trackMCReco/after/hIsPhysicalPrimary", "", {HistType::kTH1D, {{2, 0, 2}}}); - registry.add("trackMCReco/hTrackSize_unFiltered", "", {HistType::kTH1D, {{100, 0, 200000}}}); - registry.add("trackMCReco/hTrackSize_Filtered", "", {HistType::kTH1D, {{100, 0, 20000}}}); - 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::kTH1D, {axisPt}}); - registry.add("trackMCReco/after/incl/hPt_proton", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCReco/after/incl/hPt_pion", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCReco/after/incl/hPt_kaon", "", {HistType::kTH1D, {axisPt}}); - registry.addClone("trackMCReco/after/incl/", "trackMCReco/before/pos/"); - registry.addClone("trackMCReco/after/incl/", "trackMCReco/before/neg/"); + registry.add("trackMCReco/after/hIsPhysicalPrimary", "", {HistType::kTH2D, {{2, 0, 2}, axisCentrality}}); + 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}}); + registry.add("trackMCReco/after/incl/hPt_kaon", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); + // Clone into particles and before/after + registry.addClone("trackMCReco/after/incl/", "trackMCReco/after/pos/"); + registry.addClone("trackMCReco/after/incl/", "trackMCReco/after/neg/"); registry.addClone("trackMCReco/after/", "trackMCReco/before/"); } if (doprocessData) { + registry.add("QQCorrelations/qAqCX", "", kTProfile, {axisCent}); + registry.add("QQCorrelations/qAqCY", "", kTProfile, {axisCent}); + registry.add("QQCorrelations/qAqCXY", "", kTProfile, {axisCent}); + registry.add("QQCorrelations/qAXqCY", "", kTProfile, {axisCent}); + registry.add("QQCorrelations/qAYqCX", "", kTProfile, {axisCent}); + registry.add("QQCorrelations/qAXYqCXY", "", kTProfile, {axisCent}); + if (cfgFillGeneralV1Histos) { // track properties per centrality and per eta, pt bin registry.add("incl/vnC_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); @@ -515,60 +536,40 @@ struct FlowSP { registry.add("incl/vnFull_eta_EP", "", kTProfile2D, {axisEtaVn, axisCentrality}); } if (cfgFillEventPlaneQA) { - registry.add("QA/hSPplaneA", "hSPplaneA", kTH1D, {axisPhiPlane}); - registry.add("QA/hSPplaneC", "hSPplaneC", kTH1D, {axisPhiPlane}); - registry.add("QA/hSPplaneFull", "hSPplaneFull", kTH1D, {axisPhiPlane}); - registry.add("QA/hCosPhiACosPhiC", "hCosPhiACosPhiC; Centrality(%); #LT Cos(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); - registry.add("QA/hSinPhiASinPhiC", "hSinPhiASinPhiC; Centrality(%); #LT Sin(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); - registry.add("QA/hSinPhiACosPhiC", "hSinPhiACosPhiC; Centrality(%); #LT Sin(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); - registry.add("QA/hCosPhiASinsPhiC", "hCosPhiASinsPhiC; Centrality(%); #LT Cos(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); - registry.add("QA/hFullEvPlaneRes", "hFullEvPlaneRes; Centrality(%); -#LT Cos(#Psi^{A} - #Psi^{C})#GT ", kTProfile, {axisCent}); - registry.add("QA/after/PsiA_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); - registry.add("QA/after/PsiC_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); - registry.add("QA/after/PsiFull_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); - registry.add("QA/after/PsiA_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); - registry.add("QA/after/PsiC_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); - registry.add("QA/after/PsiFull_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); - registry.add("QA/after/PsiA_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); - registry.add("QA/after/PsiC_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); - registry.add("QA/after/PsiFull_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); - registry.add("QA/after/PsiA_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); - registry.add("QA/after/PsiC_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); - registry.add("QA/after/PsiFull_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); + histos.add("QA/hSPplaneA", "hSPplaneA", kTH1D, {axisPhiPlane}); + histos.add("QA/hSPplaneC", "hSPplaneC", kTH1D, {axisPhiPlane}); + histos.add("QA/hSPplaneFull", "hSPplaneFull", kTH1D, {axisPhiPlane}); + histos.add("QA/hCosPhiACosPhiC", "hCosPhiACosPhiC; Centrality(%); #LT Cos(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); + histos.add("QA/hSinPhiASinPhiC", "hSinPhiASinPhiC; Centrality(%); #LT Sin(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); + histos.add("QA/hSinPhiACosPhiC", "hSinPhiACosPhiC; Centrality(%); #LT Sin(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); + histos.add("QA/hCosPhiASinsPhiC", "hCosPhiASinsPhiC; Centrality(%); #LT Cos(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); + histos.add("QA/hFullEvPlaneRes", "hFullEvPlaneRes; Centrality(%); -#LT Cos(#Psi^{A} - #Psi^{C})#GT ", kTProfile, {axisCent}); } if (cfgFillEventQA) { - registry.add("QA/qAqCX", "", kTProfile, {axisCent}); - registry.add("QA/qAqCY", "", kTProfile, {axisCent}); - registry.add("QA/qAqCXY", "", kTProfile, {axisCent}); - registry.add("QA/qAXqCY", "", kTProfile, {axisCent}); - registry.add("QA/qAYqCX", "", kTProfile, {axisCent}); - registry.add("QA/qAXYqCXY", "", kTProfile, {axisCent}); - registry.add("QA/hCentFull", " ; Centrality (%); ", {HistType::kTH1D, {axisCent}}); + histos.add("QA/hCentFull", " ; Centrality (%); ", {HistType::kTH1D, {axisCent}}); } } // end of doprocessData - if (cfgFillQABefore && (cfgFillEventQA || cfgFillPIDQA)) - registry.addClone("QA/after/", "QA/before/"); - - if (cfgFillPID || cfgFillPIDQA) { - registry.addClone("incl/pion/", "incl/kaon/"); + if (cfgFillChargeDependence || cfgFillPID) { registry.addClone("incl/pion/", "incl/proton/"); - registry.addClone("incl/pion/", "incl/unidentified/"); - } - if (cfgFillChargeDependence || cfgFillPIDQA) { + registry.addClone("incl/pion/", "incl/kaon/"); registry.addClone("incl/", "pos/"); registry.addClone("incl/", "neg/"); } + if (cfgFillPIDQA) { + histos.addClone("incl/", "pos/"); + histos.addClone("incl/", "neg/"); + } + } else if (doprocessMCGen) { registry.add("trackMCGen/nCollReconstructedPerMcCollision", "", {HistType::kTH1D, {{10, -5, 5}}}); - registry.add("trackMCGen/after/incl/hPt_hadron", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/after/incl/hPt_proton", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/after/incl/hPt_pion", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/after/incl/hPt_kaon", "", {HistType::kTH1D, {axisPt}}); + registry.add("trackMCGen/after/incl/hPt_hadron", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); + registry.add("trackMCGen/after/incl/hPt_proton", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); + registry.add("trackMCGen/after/incl/hPt_pion", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); + registry.add("trackMCGen/after/incl/hPt_kaon", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); registry.add("trackMCGen/after/incl/phi_eta_vtxZ_gen", "", {HistType::kTH3D, {axisPhi, axisEta, axisVz}}); - registry.addClone("trackMCGen/after/incl/", "trackMCGen/before/pos/"); - registry.addClone("trackMCGen/after/incl/", "trackMCGen/before/neg/"); - if (cfgFillQABefore) - registry.addClone("trackMCGen/after/", "trackMCGen/before/"); + registry.addClone("trackMCGen/after/incl/", "trackMCGen/after/pos/"); + registry.addClone("trackMCGen/after/incl/", "trackMCGen/after/neg/"); + registry.addClone("trackMCGen/after/", "trackMCGen/before/"); } if (cfgEvSelsUseAdditionalEventCut) { @@ -636,7 +637,7 @@ struct FlowSP { return kUnidentified; // No PID information available } - std::unordered_map usedNSigma = {{usedNSigmaPi, kPion}, {usedNSigmaKa, kKaon}, {usedNSigmaPr, kProton}}; + std::unordered_map usedNSigma = {{usedNSigmaPi, kPions}, {usedNSigmaKa, kKaons}, {usedNSigmaPr, kProtons}}; int nIdentified = 0; int valPID = 0; @@ -775,7 +776,7 @@ struct FlowSP { { if (!collision.sel8()) return 0; - registry.fill(HIST("hEventCount"), evSel_sel8); + histos.fill(HIST("hEventCount"), evSel_sel8); // Occupancy if (cfgEvSelsDoOccupancySel) { @@ -783,7 +784,7 @@ struct FlowSP { if (occupancy > cfgEvSelsMaxOccupancy) { return 0; } - registry.fill(HIST("hEventCount"), evSel_occupancy); + histos.fill(HIST("hEventCount"), evSel_occupancy); } if (cfgEvSelsTVXinTRD) { @@ -792,7 +793,7 @@ struct FlowSP { // "CMTVX-B-NOPF-TRD,minbias_TVX" return 0; } - registry.fill(HIST("hEventCount"), evSel_kTVXinTRD); + histos.fill(HIST("hEventCount"), evSel_kTVXinTRD); } if (cfgEvSelsNoSameBunchPileupCut) { @@ -801,7 +802,7 @@ struct FlowSP { // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof return 0; } - registry.fill(HIST("hEventCount"), evSel_kNoSameBunchPileup); + histos.fill(HIST("hEventCount"), evSel_kNoSameBunchPileup); } if (cfgEvSelsIsGoodZvtxFT0vsPV) { if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { @@ -809,14 +810,14 @@ struct FlowSP { // use this cut at low multiplicities with caution return 0; } - registry.fill(HIST("hEventCount"), evSel_kIsGoodZvtxFT0vsPV); + histos.fill(HIST("hEventCount"), evSel_kIsGoodZvtxFT0vsPV); } if (cfgEvSelsNoCollInTimeRangeStandard) { if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { // Rejection of the collisions which have other events nearby return 0; } - registry.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeStandard); + histos.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeStandard); } if (cfgEvSelsIsVertexITSTPC) { @@ -824,7 +825,7 @@ struct FlowSP { // selects collisions with at least one ITS-TPC track, and thus rejects vertices built from ITS-only tracks return 0; } - registry.fill(HIST("hEventCount"), evSel_kIsVertexITSTPC); + histos.fill(HIST("hEventCount"), evSel_kIsVertexITSTPC); } if (cfgEvSelsUseAdditionalEventCut) { @@ -851,7 +852,7 @@ struct FlowSP { if (multTrk > fMultCutHigh->Eval(collision.centFT0C())) return 0; - registry.fill(HIST("hEventCount"), evSel_MultCuts); + histos.fill(HIST("hEventCount"), evSel_MultCuts); } if (cfgEvSelsIsGoodITSLayersAll) { @@ -860,7 +861,7 @@ struct FlowSP { // https://indico.cern.ch/event/1493023/ (09-01-2025) return 0; } - registry.fill(HIST("hEventCount"), evSel_kIsGoodITSLayersAll); + histos.fill(HIST("hEventCount"), evSel_kIsGoodITSLayersAll); } return 1; @@ -871,17 +872,17 @@ struct FlowSP { { if (std::fabs(track.eta()) > cfgTrackSelsEta) return false; - registry.fill(HIST("hTrackCount"), trackSel_Eta); + histos.fill(HIST("hTrackCount"), trackSel_Eta); if (track.pt() < cfgTrackSelsPtmin || track.pt() > cfgTrackSelsPtmax) return false; - registry.fill(HIST("hTrackCount"), trackSel_Pt); + histos.fill(HIST("hTrackCount"), trackSel_Pt); if (track.dcaXY() > cfgTrackSelsDCAxy) return false; - registry.fill(HIST("hTrackCount"), trackSel_DCAxy); + histos.fill(HIST("hTrackCount"), trackSel_DCAxy); if (track.dcaZ() > cfgTrackSelsDCAz) return false; @@ -889,15 +890,15 @@ struct FlowSP { if (cfgTrackSelsDoDCApt && std::fabs(track.dcaZ()) > (cfgTrackSelsDCApt1 * cfgTrackSelsDCApt2) / (std::pow(track.pt(), 1.1))) return false; - registry.fill(HIST("hTrackCount"), trackSel_DCAz); + histos.fill(HIST("hTrackCount"), trackSel_DCAz); if (track.tpcNClsFound() < cfgTrackSelsNcls) return false; - registry.fill(HIST("hTrackCount"), trackSel_NCls); + histos.fill(HIST("hTrackCount"), trackSel_NCls); if (track.tpcFractionSharedCls() > cfgTrackSelsFshcls) return false; - registry.fill(HIST("hTrackCount"), trackSel_FshCls); + histos.fill(HIST("hTrackCount"), trackSel_FshCls); double phimodn = track.phi(); if (field < 0) // for negative polarity field @@ -909,16 +910,16 @@ 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) - registry.fill(HIST("QA/before/pt_phi"), track.pt(), phimodn); + if (cfgFillTrackQA && cfgFillQABefore) + histos.fill(HIST("incl/QA/before/pt_phi"), track.pt(), phimodn); if (cfgTrackSelsUseAdditionalTrackCut) { if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) return false; // reject track } if (cfgFillTrackQA) - registry.fill(HIST("QA/after/pt_phi"), track.pt(), phimodn); - registry.fill(HIST("hTrackCount"), trackSel_TPCBoundary); + histos.fill(HIST("incl/QA/after/pt_phi"), track.pt(), phimodn); + histos.fill(HIST("hTrackCount"), trackSel_TPCBoundary); return true; } @@ -930,21 +931,21 @@ struct FlowSP { static constexpr std::string_view Time[] = {"before", "after"}; - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0C"), collision.centFT0C(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentNGlobal"), collision.centNGlobal(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0M"), collision.centFT0M(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFV0A"), collision.centFV0A(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_centT0C"), collision.centFT0C(), tracks.size(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multT0A"), collision.multFT0A(), tracks.size(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multV0A"), collision.multFV0A(), tracks.size(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multV0A_multT0A"), collision.multFT0A(), collision.multFV0A(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multT0C_centT0C"), collision.centFT0C(), collision.multFT0C(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0Cvariant1"), collision.centFT0C(), collision.centFT0CVariant1(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0M"), collision.centFT0C(), collision.centFT0M(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFV0A"), collision.centFT0C(), collision.centFV0A(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentNGlobal"), collision.centFT0C(), collision.centNGlobal(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0C"), collision.centFT0C(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentNGlobal"), collision.centNGlobal(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0M"), collision.centFT0M(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFV0A"), collision.centFV0A(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_centT0C"), collision.centFT0C(), tracks.size(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multT0A"), collision.multFT0A(), tracks.size(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multV0A"), collision.multFV0A(), tracks.size(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multV0A_multT0A"), collision.multFT0A(), collision.multFV0A(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multT0C_centT0C"), collision.centFT0C(), collision.multFT0C(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0Cvariant1"), collision.centFT0C(), collision.centFT0CVariant1(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0M"), collision.centFT0C(), collision.centFT0M(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFV0A"), collision.centFT0C(), collision.centFV0A(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentNGlobal"), collision.centFT0C(), collision.centNGlobal(), centWeight); if (cfgFillEventPlaneQA) { if constexpr (o2::framework::has_type_v) { @@ -952,18 +953,18 @@ struct FlowSP { double psiC = 1.0 * std::atan2(collision.qyC(), collision.qxC()); double psiFull = 1.0 * std::atan2(collision.qyA() + collision.qyC(), collision.qxA() + collision.qxC()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Cent"), psiA, collision.centFT0C(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Cent"), psiC, collision.centFT0C(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Cent"), psiFull, collision.centFT0C(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vx"), psiA, collision.vx(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vx"), psiC, collision.vx(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vx"), psiFull, collision.vx(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vy"), psiA, collision.vy(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vy"), psiC, collision.vy(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vy"), psiFull, collision.vy(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vz"), psiA, collision.posZ(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vz"), psiC, collision.posZ(), centWeight); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vz"), psiFull, collision.posZ(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Cent"), psiA, collision.centFT0C(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Cent"), psiC, collision.centFT0C(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Cent"), psiFull, collision.centFT0C(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vx"), psiA, collision.vx(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vx"), psiC, collision.vx(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vx"), psiFull, collision.vx(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vy"), psiA, collision.vy(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vy"), psiC, collision.vy(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vy"), psiFull, collision.vy(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vz"), psiA, collision.posZ(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vz"), psiC, collision.posZ(), centWeight); + histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vz"), psiFull, collision.posZ(), centWeight); } } return; @@ -1029,7 +1030,7 @@ struct FlowSP { registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy_pt"), track.pt(), centrality, (uy * qyC) / std::sqrt(std::fabs(corrQQy)), weight); } - if (cfgFillEventPlane) { + if (cfgFillEventPlane && pt == 0) { // only fill for inclusive! registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_eta_EP"), track.eta(), centrality, vnA, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_eta_EP"), track.eta(), centrality, vnC, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnFull_eta_EP"), track.eta(), centrality, vnFull, weight); @@ -1084,25 +1085,16 @@ struct FlowSP { static constexpr std::string_view Time[] = {"before/", "after/"}; // NOTE: species[kUnidentified] = "" (when no PID) - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt"), track.pt(), wacc * weff); - if (track.eta() > 0) { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_forward"), track.pt(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_forward_uncorrected"), track.pt()); - } else { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_backward"), track.pt(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_backward_uncorrected"), track.pt()); - } - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi"), track.phi(), wacc); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_uncorrected"), track.phi()); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hEta"), track.eta(), wacc); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hEta_uncorrected"), track.eta()); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), vz); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz_corrected"), track.phi(), track.eta(), vz, wacc); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsFound(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_Pt"), track.phi(), track.eta(), track.pt()); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_Pt_corrected"), track.phi(), track.eta(), track.pt(), wacc * weff); + + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), vz); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz_corrected"), track.phi(), track.eta(), vz, wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsFound(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls(), wacc * weff); } template @@ -1113,90 +1105,85 @@ struct FlowSP { static constexpr std::string_view Time[] = {"before/", "after/"}; // NOTE: species[kUnidentified] = "" (when no PID) - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt"), track.pt(), centrality, wacc * weff); - if (track.eta() > 0) { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_forward"), track.pt(), centrality, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_forward_uncorrected"), track.pt(), centrality); - } else { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_backward"), track.pt(), centrality, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_backward_uncorrected"), track.pt(), centrality); - } - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi"), track.phi(), centrality, wacc); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_uncorrected"), track.phi(), centrality); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hEta"), track.eta(), centrality, wacc); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hEta_uncorrected"), track.eta(), centrality); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), vz); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz_corrected"), track.phi(), track.eta(), vz, wacc); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsFound(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta"), track.pt(), track.eta(), centrality, wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta_uncorrected"), track.pt(), track.eta(), centrality); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta"), track.phi(), track.eta(), centrality, wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_uncorrected"), track.phi(), track.eta(), centrality); + + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), vz); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz_corrected"), track.phi(), track.eta(), vz, wacc); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsFound(), wacc * weff); + histos.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls(), wacc * weff); } template inline void fillPIDQA(TrackObject track) { - if (!cfgFillPIDQA) + if (!cfgFillPIDQA || !cfgFillTrackQA) return; - registry.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPi()); - registry.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaPi()); - registry.fill(HIST(Charge[ct]) + HIST("kaon/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaKa()); - registry.fill(HIST(Charge[ct]) + HIST("kaon/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaKa()); - registry.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPr()); - registry.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaPr()); + histos.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPi()); + histos.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaPi()); + histos.fill(HIST(Charge[ct]) + HIST("kaon/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaKa()); + histos.fill(HIST(Charge[ct]) + HIST("kaon/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaKa()); + histos.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPr()); + histos.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaPr()); + + histos.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_Pt"), track.phi(), track.eta(), track.pt()); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hdEdxTPC_pt"), track.pt(), track.tpcSignal()); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hBetaTOF_pt"), track.pt(), track.beta()); + histos.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hdEdxTPC_pt"), track.pt(), track.tpcSignal()); + histos.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hBetaTOF_pt"), track.pt(), track.beta()); } template - inline void fillMCPtHistos(TrackObject track, int pdgCode) + inline void fillMCPtHistos(TrackObject track, int pdgCode, float centrality) { static constexpr std::string_view Time[] = {"before/", "after/"}; static constexpr std::string_view Mode[] = {"Gen/", "Reco/"}; - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_hadron"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_hadron"), track.pt(), track.eta(), centrality); if (pdgCode > 0) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_hadron"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_hadron"), track.pt(), track.eta(), centrality); } else { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_hadron"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_hadron"), track.pt(), track.eta(), centrality); } if (pdgCode == kPiPlus || pdgCode == kPiMinus) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_pion"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_pion"), track.pt(), track.eta(), centrality); if (pdgCode == kPiPlus) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_pion"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_pion"), track.pt(), track.eta(), centrality); } else { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_pion"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_pion"), track.pt(), track.eta(), centrality); } } else if (pdgCode == kKPlus || pdgCode == kKMinus) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_kaon"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_kaon"), track.pt(), track.eta(), centrality); if (pdgCode == kKPlus) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_kaon"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_kaon"), track.pt(), track.eta(), centrality); } else { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_kaon"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_kaon"), track.pt(), track.eta(), centrality); } } else if (pdgCode == kProton || pdgCode == kProtonBar) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_proton"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("incl/hPt_proton"), track.pt(), track.eta(), centrality); if (pdgCode == kProton) { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_proton"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("pos/hPt_proton"), track.pt(), track.eta(), centrality); } else { - registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_proton"), track.pt()); + registry.fill(HIST("trackMC") + HIST(Mode[md]) + HIST(Time[ft]) + HIST("neg/hPt_proton"), track.pt(), track.eta(), centrality); } } } - template - inline void fillPrimaryHistos(McParticleObject mcparticle) + template + inline void fillPrimaryHistos(McParticleObject mcparticle, float centrality) { static constexpr std::string_view Time[] = {"/before", "/after"}; if (!mcparticle.isPhysicalPrimary()) { - registry.fill(HIST("trackMCReco") + HIST(Time[md]) + HIST("/hIsPhysicalPrimary"), 0); + registry.fill(HIST("trackMCReco") + HIST(Time[ft]) + HIST("/hIsPhysicalPrimary"), 0, centrality); } else { - registry.fill(HIST("trackMCReco") + HIST(Time[md]) + HIST("/hIsPhysicalPrimary"), 1); + registry.fill(HIST("trackMCReco") + HIST(Time[ft]) + HIST("/hIsPhysicalPrimary"), 1, centrality); } } @@ -1226,9 +1213,9 @@ struct FlowSP { } } - void processData(UsedCollisions::iterator const& collision, aod::BCsWithTimestamps const&, UsedTracks const& tracks) + void processData(ZDCCollisions::iterator const& collision, aod::BCsWithTimestamps const&, UsedTracks const& tracks) { - registry.fill(HIST("hEventCount"), evSel_FilteredEvent); + histos.fill(HIST("hEventCount"), evSel_FilteredEvent); auto bc = collision.bc_as(); int standardMagField = 99999; auto field = (cfgMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfgMagField; @@ -1262,7 +1249,7 @@ struct FlowSP { if (collision.isSelected()) { - registry.fill(HIST("hEventCount"), evSel_isSelectedZDC); + histos.fill(HIST("hEventCount"), evSel_isSelectedZDC); double qxA = collision.qxA(); double qyA = collision.qyA(); @@ -1276,30 +1263,32 @@ struct FlowSP { // https://twiki.cern.ch/twiki/pub/ALICE/DirectedFlowAnalysisNote/vn_ZDC_ALICE_INT_NOTE_version02.pdf double psiFull = 1.0 * std::atan2(qyA + qyC, qxA + qxC); + // always fill these histograms! + registry.fill(HIST("QQCorrelations/qAqCXY"), centrality, qxA * qxC + qyA * qyC); + registry.fill(HIST("QQCorrelations/qAXqCY"), centrality, qxA * qyC); + registry.fill(HIST("QQCorrelations/qAYqCX"), centrality, qyA * qxC); + registry.fill(HIST("QQCorrelations/qAXYqCXY"), centrality, qyA * qxC + qxA * qyC); + registry.fill(HIST("QQCorrelations/qAqCX"), centrality, qxA * qxC); + registry.fill(HIST("QQCorrelations/qAqCY"), centrality, qyA * qyC); + if (cfgFillEventQA) { - registry.fill(HIST("QA/hCentFull"), centrality, 1); - registry.fill(HIST("QA/qAqCXY"), centrality, qxA * qxC + qyA * qyC); - registry.fill(HIST("QA/qAXqCY"), centrality, qxA * qyC); - registry.fill(HIST("QA/qAYqCX"), centrality, qyA * qxC); - registry.fill(HIST("QA/qAXYqCXY"), centrality, qyA * qxC + qxA * qyC); - registry.fill(HIST("QA/qAqCX"), centrality, qxA * qxC); - registry.fill(HIST("QA/qAqCY"), centrality, qyA * qyC); + histos.fill(HIST("QA/hCentFull"), centrality, 1); } if (cfgFillEventPlaneQA) { - registry.fill(HIST("QA/hSPplaneA"), psiA, 1); - registry.fill(HIST("QA/hSPplaneC"), psiC, 1); - registry.fill(HIST("QA/hSPplaneFull"), psiFull, 1); - registry.fill(HIST("QA/hCosPhiACosPhiC"), centrality, std::cos(psiA) * std::cos(psiC)); - registry.fill(HIST("QA/hSinPhiASinPhiC"), centrality, std::sin(psiA) * std::sin(psiC)); - registry.fill(HIST("QA/hSinPhiACosPhiC"), centrality, std::sin(psiA) * std::cos(psiC)); - registry.fill(HIST("QA/hCosPhiASinsPhiC"), centrality, std::cos(psiA) * std::sin(psiC)); - registry.fill(HIST("QA/hFullEvPlaneRes"), centrality, -1 * std::cos(psiA - psiC)); + histos.fill(HIST("QA/hSPplaneA"), psiA, 1); + histos.fill(HIST("QA/hSPplaneC"), psiC, 1); + histos.fill(HIST("QA/hSPplaneFull"), psiFull, 1); + histos.fill(HIST("QA/hCosPhiACosPhiC"), centrality, std::cos(psiA) * std::cos(psiC)); + histos.fill(HIST("QA/hSinPhiASinPhiC"), centrality, std::sin(psiA) * std::sin(psiC)); + histos.fill(HIST("QA/hSinPhiACosPhiC"), centrality, std::sin(psiA) * std::cos(psiC)); + histos.fill(HIST("QA/hCosPhiASinsPhiC"), centrality, std::cos(psiA) * std::sin(psiC)); + histos.fill(HIST("QA/hFullEvPlaneRes"), centrality, -1 * std::cos(psiA - psiC)); } if (centrality > cfgCentMax || centrality < cfgCentMin) return; - registry.fill(HIST("hEventCount"), evSel_CentCuts); + histos.fill(HIST("hEventCount"), evSel_CentCuts); // Load correlations and SP resolution needed for Scalar Product and event plane methods. // Only load once! @@ -1348,7 +1337,7 @@ struct FlowSP { int trackPID = (cfgFillPID || cfgFillPIDQA) ? getTrackPID(track) : kUnidentified; if (cfgFillPIDQA) - registry.fill(HIST("hPIDcounts"), trackPID, track.pt()); + histos.fill(HIST("hPIDcounts"), trackPID, track.pt()); float weff = 1., wacc = 1.; float weffP = 1., waccP = 1.; @@ -1357,7 +1346,7 @@ struct FlowSP { if (track.sign() == 0.0) continue; - registry.fill(HIST("hTrackCount"), trackSel_ZeroCharge); + histos.fill(HIST("hTrackCount"), trackSel_ZeroCharge); bool pos = (track.sign() > 0) ? true : false; if (cfgFillQABefore) { @@ -1365,14 +1354,14 @@ struct FlowSP { case kUnidentified: fillAllQA(track, vtxz, centrality, pos); break; - case kPion: - fillAllQA(track, vtxz, centrality, pos); + case kPions: + fillAllQA(track, vtxz, centrality, pos); break; - case kKaon: - fillAllQA(track, vtxz, centrality, pos); + case kKaons: + fillAllQA(track, vtxz, centrality, pos); break; - case kProton: - fillAllQA(track, vtxz, centrality, pos); + case kProtons: + fillAllQA(track, vtxz, centrality, pos); break; } } @@ -1383,26 +1372,19 @@ struct FlowSP { // constrain angle to 0 -> [0,0+2pi] auto phi = RecoDecay::constrainAngle(track.phi(), 0); - if (cfguseNUA2D && cfgFillWeights) { - registry.fill(HIST("weights/hPhi_Eta_vz"), phi, track.eta(), vtxz, 1); - if (pos) { - registry.fill(HIST("weights/hPhi_Eta_vz_positive"), phi, track.eta(), vtxz, 1); - } else { - registry.fill(HIST("weights/hPhi_Eta_vz_negative"), phi, track.eta(), vtxz, 1); - } - } - // Fill NUA weights (last 0 is for Data see GFWWeights class (not a weight)) + // ToDo: Add pi, ka, proton here! if (cfgFillWeights) { fWeights->fill(phi, track.eta(), vtxz, track.pt(), centrality, 0); + registry.fill(HIST("weights2D/hPhi_Eta_vz"), phi, track.eta(), vtxz, 1); } - if (cfgFillWeightsPOS) { - if (pos) - fWeightsPOS->fill(phi, track.eta(), vtxz, track.pt(), centrality, 0); + if (cfgFillWeightsPOS && pos) { + fWeightsPOS->fill(phi, track.eta(), vtxz, track.pt(), centrality, 0); + registry.fill(HIST("weights2D/hPhi_Eta_vz_positive"), phi, track.eta(), vtxz, 1); } - if (cfgFillWeightsNEG) { - if (!pos) - fWeightsNEG->fill(phi, track.eta(), vtxz, track.pt(), centrality, 0); + if (cfgFillWeightsNEG && !pos) { + fWeightsNEG->fill(phi, track.eta(), vtxz, track.pt(), centrality, 0); + registry.fill(HIST("weights2D/hPhi_Eta_vz_negative"), phi, track.eta(), vtxz, 1); } // Set weff and wacc for inclusive, negative and positive hadrons @@ -1413,20 +1395,20 @@ struct FlowSP { if (!pos && !setCurrentParticleWeights(kNegative, weffN, waccN, phi, track.eta(), track.pt(), vtxz)) continue; - registry.fill(HIST("hTrackCount"), trackSel_ParticleWeights); + histos.fill(HIST("hTrackCount"), trackSel_ParticleWeights); switch (trackPID) { case kUnidentified: fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); break; - case kPion: - fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); + case kPions: + fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); break; - case kKaon: - fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); + case kKaons: + fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); break; - case kProton: - fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); + case kProtons: + fillAllQA(track, vtxz, centrality, pos, wacc, weff, waccP, weffP, waccN, weffN); break; } @@ -1446,6 +1428,30 @@ struct FlowSP { double vnFull = std::cos(cfgHarm * (phi - psiFull)) / evPlaneRes; fillHistograms(track, wacc, weff, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + + // NOTE: these are not the right wacc and weff!! Need to do for each particle species! This is just to test for now. + if (cfgFillPID) { + if (trackPID == kPions) { + fillHistograms(track, wacc, weff, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + if (pos) + fillHistograms(track, waccP, weffP, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + else + fillHistograms(track, waccN, weffN, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + } else if (trackPID == kKaons) { + fillHistograms(track, wacc, weff, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + if (pos) + fillHistograms(track, waccP, weffP, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + else + fillHistograms(track, waccN, weffN, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + } else if (trackPID == kProtons) { + fillHistograms(track, wacc, weff, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + if (pos) + fillHistograms(track, waccP, weffP, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + else + fillHistograms(track, waccN, weffN, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + } + } + if (cfgFillChargeDependence) { if (pos) { fillHistograms(track, waccP, weffP, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); @@ -1477,7 +1483,7 @@ struct FlowSP { centrality = collision.centNGlobal(); if (cfgFillQABefore) - fillEventQA(collision, tracks); + fillEventQA(collision, filteredTracks); if (!eventSelected(collision, filteredTracks.size())) return; @@ -1485,34 +1491,53 @@ struct FlowSP { if (centrality > cfgCentMax || centrality < cfgCentMin) return; - registry.fill(HIST("hEventCount"), evSel_CentCuts); + histos.fill(HIST("hEventCount"), evSel_CentCuts); if (!collision.has_mcCollision()) { LOGF(info, "No mccollision found for this collision"); return; } - fillEventQA(collision, tracks); + fillEventQA(collision, filteredTracks); - registry.fill(HIST("trackMCReco/hTrackSize_unFiltered"), tracks.size()); - registry.fill(HIST("trackMCReco/hTrackSize_Filtered"), filteredTracks.size()); + registry.fill(HIST("trackMCReco/hTrackSize_unFiltered"), tracks.size(), centrality); + registry.fill(HIST("trackMCReco/hTrackSize_Filtered"), filteredTracks.size(), centrality); for (const auto& track : filteredTracks) { auto mcParticle = track.mcParticle(); if (track.sign() == 0.0) continue; - registry.fill(HIST("hTrackCount"), trackSel_ZeroCharge); + histos.fill(HIST("hTrackCount"), trackSel_ZeroCharge); + + fillMCPtHistos(track, mcParticle.pdgCode(), centrality); + bool pos = (track.sign() > 0) ? true : false; - fillMCPtHistos(track, mcParticle.pdgCode()); + fillPrimaryHistos(mcParticle, centrality); - fillTrackQA(track, vtxz); + // This neglects PID (for now) later use getPID like in data. + if (cfgFillQABefore) { + switch (std::abs(mcParticle.pdgCode())) { + case kPions: + fillAllQA(track, vtxz, centrality, pos); + break; + case kKaons: + fillAllQA(track, vtxz, centrality, pos); + break; + case kProtons: + fillAllQA(track, vtxz, centrality, pos); + break; + default: + fillAllQA(track, vtxz, centrality, pos); + } + } if (!trackSelected(track, field)) continue; - fillMCPtHistos(track, mcParticle.pdgCode()); + fillMCPtHistos(track, mcParticle.pdgCode(), centrality); fillTrackQA(track, vtxz); + fillPrimaryHistos(mcParticle, centrality); } // end of track loop } @@ -1551,7 +1576,8 @@ struct FlowSP { if (cfgCentNGlobal) centrality = col.centNGlobal(); - fillEventQA(col, trackSlice); + if (cfgFillQABefore) + fillEventQA(col, filteredTrackSlice); if (trackSlice.size() < 1) { colSelected = false; @@ -1566,9 +1592,9 @@ struct FlowSP { colSelected = false; continue; } - registry.fill(HIST("hEventCount"), evSel_CentCuts); + histos.fill(HIST("hEventCount"), evSel_CentCuts); - fillEventQA(col, trackSlice); + fillEventQA(col, filteredTrackSlice); } // leave reconstructed collision loop @@ -1594,7 +1620,7 @@ struct FlowSP { bool pos = (charge > 0) ? true : false; - fillMCPtHistos(particle, pdgCode); + fillMCPtHistos(particle, pdgCode, centrality); registry.fill(HIST("trackMCGen/before/incl/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); @@ -1607,7 +1633,7 @@ struct FlowSP { if (particle.eta() < -cfgTrackSelsEta || particle.eta() > cfgTrackSelsEta || particle.pt() < cfgTrackSelsPtmin || particle.pt() > cfgTrackSelsPtmax) continue; - fillMCPtHistos(particle, pdgCode); + fillMCPtHistos(particle, pdgCode, centrality); registry.fill(HIST("trackMCGen/after/incl/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index 9f27ffa0005..a7691188f19 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -36,6 +36,7 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/runDataProcessing.h" #include +#include #include "TList.h" #include @@ -141,6 +142,13 @@ struct FlowTask { TF1* fMultMultV0ACutHigh = nullptr; TF1* fT0AV0AMean = nullptr; TF1* fT0AV0ASigma = nullptr; + // for TPC sector boundary + O2_DEFINE_CONFIGURABLE(cfgShowTPCsectorOverlap, bool, true, "Draw TPC sector overlap") + O2_DEFINE_CONFIGURABLE(cfgRejectionTPCsectorOverlap, bool, false, "rejection for TPC sector overlap") + O2_DEFINE_CONFIGURABLE(cfgMagnetField, std::string, "GLO/Config/GRPMagField", "CCDB path to Magnet field object") + ConfigurableAxis axisPhiMod{"axisPhiMod", {100, 0, constants::math::PI / 9}, "fmod(#varphi,#pi/9)"}; + TF1* fPhiCutLow = nullptr; + TF1* fPhiCutHigh = nullptr; } cfgFuncParas; ConfigurableAxis axisPtHist{"axisPtHist", {100, 0., 10.}, "pt axis for histograms"}; @@ -283,6 +291,8 @@ struct FlowTask { registry.add("hEta", "#eta distribution", {HistType::kTH1D, {axisEta}}); registry.add("hPt", "p_{T} distribution before cut", {HistType::kTH1D, {axisPtHist}}); registry.add("hPtRef", "p_{T} distribution after cut", {HistType::kTH1D, {axisPtHist}}); + registry.add("pt_phi_bef", "before cut;p_{T};#phi_{modn}", {HistType::kTH2D, {axisPt, cfgFuncParas.axisPhiMod}}); + registry.add("pt_phi_aft", "after cut;p_{T};#phi_{modn}", {HistType::kTH2D, {axisPt, cfgFuncParas.axisPhiMod}}); registry.add("hChi2prTPCcls", "#chi^{2}/cluster for the TPC track segment", {HistType::kTH1D, {{100, 0., 5.}}}); registry.add("hChi2prITScls", "#chi^{2}/cluster for the ITS track", {HistType::kTH1D, {{100, 0., 50.}}}); registry.add("hnTPCClu", "Number of found TPC clusters", {HistType::kTH1D, {{100, 40, 180}}}); @@ -501,6 +511,11 @@ struct FlowTask { cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); } + if (cfgFuncParas.cfgShowTPCsectorOverlap) { + cfgFuncParas.fPhiCutLow = new TF1("fPhiCutLow", "0.06/x+pi/18.0-0.06", 0, 100); + cfgFuncParas.fPhiCutHigh = new TF1("fPhiCutHigh", "0.1/x+pi/18.0+0.06", 0, 100); + } + if (cfgTrackDensityCorrUse) { std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, &pTEffBins[0]); @@ -730,12 +745,49 @@ struct FlowTask { return 1; } + int getMagneticField(uint64_t timestamp) + { + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp(cfgFuncParas.cfgMagnetField, timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found in %s for timestamp %llu", cfgFuncParas.cfgMagnetField.value.c_str(), timestamp); + return 0; + } + LOGF(info, "Retrieved GRP from %s for timestamp %llu with magnetic field of %d kG", cfgFuncParas.cfgMagnetField.value.c_str(), timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + template bool trackSelected(TTrack track) { return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgCutITSclu)); } + template + bool rejectionTPCoverlap(TTrack track, const int field) + { + double phimodn = track.phi(); + if (field < 0) // for negative polarity field + phimodn = o2::constants::math::TwoPI - phimodn; + if (track.sign() < 0) // for negative charge + phimodn = o2::constants::math::TwoPI - phimodn; + if (phimodn < 0) + LOGF(warning, "phi < 0: %g", phimodn); + + float middle = o2::constants::math::TwoPI / 18.0; + phimodn += middle; // to center gap in the middle + phimodn = fmod(phimodn, o2::constants::math::TwoPI / 9.0); + registry.fill(HIST("pt_phi_bef"), track.pt(), phimodn); + if (cfgFuncParas.cfgRejectionTPCsectorOverlap) { + if (phimodn < cfgFuncParas.fPhiCutHigh->Eval(track.pt()) && phimodn > cfgFuncParas.fPhiCutLow->Eval(track.pt())) + return false; // reject track + } + registry.fill(HIST("pt_phi_aft"), track.pt(), phimodn); + return true; + } + void initHadronicRate(aod::BCsWithTimestamps::iterator const& bc) { if (mRunNumber == bc.runNumber()) { @@ -844,9 +896,14 @@ struct FlowTask { // track weights float weff = 1, wacc = 1; double nTracksCorrected = 0; + int magnetfield = 0; float independent = cent; if (cfgUseNch) independent = static_cast(tracks.size()); + if (cfgFuncParas.cfgShowTPCsectorOverlap) { + // magnet field dependence cut + magnetfield = getMagneticField(bc.timestamp()); + } double psi2Est = 0, psi3Est = 0, psi4Est = 0; float wEPeff = 1; @@ -879,6 +936,8 @@ struct FlowTask { for (const auto& track : tracks) { if (!trackSelected(track)) continue; + if (cfgFuncParas.cfgShowTPCsectorOverlap && !rejectionTPCoverlap(track, magnetfield)) + continue; bool withinPtPOI = (cfgCutPtPOIMin < track.pt()) && (track.pt() < cfgCutPtPOIMax); // within POI pT range bool withinPtRef = (cfgCutPtRefMin < track.pt()) && (track.pt() < cfgCutPtRefMax); // within RF pT range if (cfgOutputNUAWeights) { diff --git a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx index a64d25c6d67..534c88d2cda 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx @@ -132,6 +132,7 @@ struct ThreeParticleCorrelations { SameKindPair pairMC{collBinningMC, 5, -1, &cache}; // Process configurables + Configurable confBfieldSwitch{"confBfieldSwitch", 0, "Switch for the detector magnetic field (1 if Pos, -1 if Neg, 0 if both)"}; Configurable confFakeV0Switch{"confFakeV0Switch", false, "Switch for the fakeV0Filter function"}; Configurable confRDSwitch{"confRDSwitch", true, "Switch for the radialDistanceFilter function"}; @@ -174,6 +175,7 @@ struct ThreeParticleCorrelations { rQARegistry.add("hEventCentrality", "hEventCentrality", {HistType::kTH1D, {{centralityAxis}}}); rQARegistry.add("hEventCentrality_MC", "hEventCentrality_MC", {HistType::kTH1D, {{centralityAxis}}}); rQARegistry.add("hEventZvtx", "hEventZvtx", {HistType::kTH1D, {{zvtxAxis}}}); + rQARegistry.add("hEventBfield", "hEventBfield", {HistType::kTH1D, {{2, -1, 1}}}); rQARegistry.add("hTrackPt", "hTrackPt", {HistType::kTH1D, {{100, 0, 4}}}); rQARegistry.add("hTrackEta", "hTrackEta", {HistType::kTH1D, {{100, -1, 1}}}); rQARegistry.add("hTrackPhi", "hTrackPhi", {HistType::kTH1D, {{100, (-1. / 2) * constants::math::PI, (5. / 2) * constants::math::PI}}}); @@ -334,8 +336,15 @@ struct ThreeParticleCorrelations { auto bc = collision.bc_as(); auto bField = getMagneticField(bc.timestamp()); + if (confBfieldSwitch != 0) { + if (std::signbit(static_cast(confBfieldSwitch)) != std::signbit(bField)) { + return; + } + } + rQARegistry.fill(HIST("hEventCentrality"), collision.centFT0C()); rQARegistry.fill(HIST("hEventZvtx"), collision.posZ()); + rQARegistry.fill(HIST("hEventBfield"), bField); // Start of the Track QA for (const auto& track : tracks) { @@ -455,6 +464,12 @@ struct ThreeParticleCorrelations { auto bc = coll_1.bc_as(); auto bField = getMagneticField(bc.timestamp()); + if (confBfieldSwitch != 0) { + if (std::signbit(static_cast(confBfieldSwitch)) != std::signbit(bField)) { + return; + } + } + for (const auto& [trigger, associate] : soa::combinations(soa::CombinationsFullIndexPolicy(v0_1, track_2))) { if (v0Filters(coll_1, trigger, tracks) && trackFilters(associate)) { if (radialDistanceFilter(trigger, associate, bField, true) && fakeV0Filter(trigger, associate)) { diff --git a/PWGCF/TableProducer/dptDptFilter.cxx b/PWGCF/TableProducer/dptDptFilter.cxx index 2fe925102b8..8dc1e100970 100644 --- a/PWGCF/TableProducer/dptDptFilter.cxx +++ b/PWGCF/TableProducer/dptDptFilter.cxx @@ -49,6 +49,7 @@ #include #include #include +#include #include using namespace o2; @@ -100,30 +101,45 @@ const char* speciesTitle[kDptDptNoOfSpecies] = {"", "e", "#mu", "#pi", "K", "p"} /// \enum BeforeAfter /// \brief when filling the histograms enum BeforeAfter { - BeforeAfterBEFORE = 0, ///< filling the histograms before selections - BeforeAfterAFTER, ///< filling the histograms after selections - BeforeAfterNOOFTIMES ///< how many times fill the histograms + BeforeAfterBEFORE = 0, ///< filling the histograms before selections + BeforeAfterBEFOREMULTCORR, ///< filling the histograms before outliers exclusion + BeforeAfterAFTER, ///< filling the histograms after selections + BeforeAfterNOOFTIMES ///< how many times fill the histograms }; -static const std::vector beforeAfterName = {"before", ""}; -static const std::vector beforeAfterSufix = {"B", "A"}; +static const std::vector beforeAfterName = {"before", "before outliers exclusion", ""}; +static const std::vector beforeAfterSufix = {"B", "BO", "A"}; /* helpers for the multiplicity axes definition */ static constexpr float MultiplicityUpperLimitBase[11][8] = { /* T0A, T0C, T0M, V0A, V0C, V0M, tracks, PV contr. tracks */ {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* no system */ - {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* pp Run2 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 50e3f, 5e3f, 400.0f}, /* pp Run2 */ {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* pPb Run2 */ {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* Pbp Run2 */ {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* PbPb Run2 */ {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* XeXe Run2 */ - {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* pp Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 50e3f, 5e3f, 400.0f}, /* pp Run3 */ {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* PbPb Run3 */ - {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* NeNe Run3 */ - {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* OO Run3 */ - {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f} /* pO Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 50e3f, 5e3f, 400.0f}, /* NeNe Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 50e3f, 5e3f, 400.0f}, /* OO Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 50e3f, 5e3f, 400.0f} /* pO Run3 */ }; +/* helpers for the multiplicity/centrality correlations exclusion formulae */ +static const std::string multiplicityCentralityCorrelationsFormulaBase[11][1] = { + /* no system */ {""}, + /* pp Run2 */ {""}, + /* pPb Run2 */ {""}, + /* Pbp Run2 */ {""}, + /* PbPb Run2 */ {""}, + /* XeXe Run2 */ {""}, + /* pp Run3 */ {""}, + /* PbPb Run3 */ {""}, + /* NeNe Run3 */ {"((221.987-0.706581*[CT0C]+0.00906828*[CT0C]*[CT0C]-23.5275*sqrt([CT0C])-2.5*(38.5823+2.00054*[CT0C]+0.0125088*[CT0C]*[CT0C]-8.47825*sqrt([CT0C])-0.273493*[CT0C]*sqrt([CT0C])))<=[MNGLTRK])&&((-0.0729502+0.79403*[MNPVC]+5.0*(0.032005+0.00372503*[MNPVC]-7.18977e-06*[MNPVC]*[MNPVC]+0.412714*sqrt([MNPVC])))>[MNGLTRK])&&((-0.0729502+0.79403*[MNPVC]-5.0*(0.032005+0.00372503*[MNPVC]-7.18977e-06*[MNPVC]*[MNPVC]+0.412714*sqrt([MNPVC])))<=[MNGLTRK])"}, + /* OO Run3 */ {"((180.584-0.211625*[CT0C]+0.00568101*[CT0C]*[CT0C]-20.9838*sqrt([CT0C])-2.5*(32.665+1.67341*[CT0C]+0.0113878*[CT0C]*[CT0C]-6.83271*sqrt([CT0C])-0.239428*[CT0C]*sqrt([CT0C])))<=[MNGLTRK])&&((-0.0533229+0.79235*[MNPVC]+5.0*(0.031512+0.0045874*[MNPVC]-1.06374e-05*[MNPVC]*[MNPVC]+0.407526*sqrt([MNPVC])))>[MNGLTRK])&&((-0.0533229+0.79235*[MNPVC]-5.0*(0.031512+0.0045874*[MNPVC]-1.06374e-05*[MNPVC]*[MNPVC]+0.407526*sqrt([MNPVC])))<=[MNGLTRK])"}, + /* pO Run3 */ {""}}; + //============================================================================================ // The DptDptFilter histogram objects // TODO: consider registering in the histogram registry @@ -393,6 +409,79 @@ struct Multiplicity { } }; +////////////////////////////////////////////////////////////////////////////////// +/// Centrality/multiplicity correlations exclusion +/// TODO: adaptation to Run 1/Run 2 +////////////////////////////////////////////////////////////////////////////////// +template +inline void storeMultiplicitiesAndCentralities(CollisionObject const& collision, TrackListObject const& tracks) +{ + /* only do it if we are tracking the centrality / multiplicity correlations */ + if (useCentralityMultiplicityCorrelationsExclusion) { + int nGlobalTracks = 0; + for (auto const& track : tracks) { + if (track.isGlobalTrack()) { + nGlobalTracks++; + } + } + for (CentMultCorrelationsParams ipar = CentMultCorrelationsMT0A; ipar < CentMultCorrelationsNOOFPARAMS; ++ipar) { + switch (ipar) { + case CentMultCorrelationsMT0A: + collisionMultiplicityCentralityObservables[ipar] = collision.multFT0A(); + break; + case CentMultCorrelationsMT0C: + collisionMultiplicityCentralityObservables[ipar] = collision.multFT0C(); + break; + case CentMultCorrelationsMT0M: + collisionMultiplicityCentralityObservables[ipar] = collision.multFT0M(); + break; + case CentMultCorrelationsMV0A: + collisionMultiplicityCentralityObservables[ipar] = collision.multFV0A(); + break; + case CentMultCorrelationsMV0C: + collisionMultiplicityCentralityObservables[ipar] = collision.multFV0C(); + break; + case CentMultCorrelationsMV0M: + collisionMultiplicityCentralityObservables[ipar] = collision.multFV0M(); + break; + case CentMultCorrelationsMNGLTRK: + collisionMultiplicityCentralityObservables[ipar] = nGlobalTracks; + break; + case CentMultCorrelationsMNPVC: + collisionMultiplicityCentralityObservables[ipar] = collision.multNTracksPV(); + break; + case CentMultCorrelationsCT0A: + if constexpr (framework::has_type_v) { + collisionMultiplicityCentralityObservables[ipar] = collision.centFT0A(); + } + break; + case CentMultCorrelationsCT0C: + if constexpr (framework::has_type_v) { + collisionMultiplicityCentralityObservables[ipar] = collision.centFT0C(); + } + break; + case CentMultCorrelationsCT0M: + if constexpr (framework::has_type_v) { + collisionMultiplicityCentralityObservables[ipar] = collision.centFT0M(); + } + break; + case CentMultCorrelationsCV0A: + if constexpr (framework::has_type_v) { + collisionMultiplicityCentralityObservables[ipar] = collision.centFV0A(); + } + break; + case CentMultCorrelationsCNTPV: + if constexpr (framework::has_type_v) { + collisionMultiplicityCentralityObservables[ipar] = collision.centNTPV(); + } + break; + default: + break; + } + } + } +} + ////////////////////////////////////////////////////////////////////////////// // The filter class ////////////////////////////////////////////////////////////////////////////// @@ -414,7 +503,11 @@ struct DptDptFilter { Configurable minOrbit{"minOrbit", -1, "Lowest orbit to track"}; Configurable maxOrbit{"maxOrbit", INT64_MAX, "Highest orbit to track"}; Configurable rctSource{"rctSource", "None", "RCT selection source: None,CBT,CBT_hadronPID,CBT_electronPID,CBT_calo,CBT_muon,CBT_muon_glo. Default: None"}; - Configurable> multiplicityUpperLimit{"multiplicityUpperLimit", {&MultiplicityUpperLimitBase[0][0], 11, 8, {systemExternalNamesMap.at(0), systemExternalNamesMap.at(1), systemExternalNamesMap.at(2), systemExternalNamesMap.at(3), systemExternalNamesMap.at(4), systemExternalNamesMap.at(5), systemExternalNamesMap.at(6), systemExternalNamesMap.at(7), systemExternalNamesMap.at(8), systemExternalNamesMap.at(9), systemExternalNamesMap.at(10)}, {multiplicitySourceConfigNamesMap.at(0), multiplicitySourceConfigNamesMap.at(1), multiplicitySourceConfigNamesMap.at(2), multiplicitySourceConfigNamesMap.at(3), multiplicitySourceConfigNamesMap.at(4), multiplicitySourceConfigNamesMap.at(5), multiplicitySourceConfigNamesMap.at(6), multiplicitySourceConfigNamesMap.at(7)}}, "Upper limits for the multiplicity observables"}; +#define SYSTEMNAME(sysid) systemExternalNamesMap.at(sysid).data() +#define MULTSRCNAME(msrcid) multiplicitySourceConfigNamesMap.at(msrcid).data() + Configurable> multiplicityUpperLimit{"multiplicityUpperLimit", {MultiplicityUpperLimitBase[0], 11, 8, {SYSTEMNAME(0), SYSTEMNAME(1), SYSTEMNAME(2), SYSTEMNAME(3), SYSTEMNAME(4), SYSTEMNAME(5), SYSTEMNAME(6), SYSTEMNAME(7), SYSTEMNAME(8), SYSTEMNAME(9), SYSTEMNAME(10)}, {MULTSRCNAME(0), MULTSRCNAME(1), MULTSRCNAME(2), MULTSRCNAME(3), MULTSRCNAME(4), MULTSRCNAME(5), MULTSRCNAME(6), MULTSRCNAME(7)}}, "Upper limits for the multiplicity observables"}; + Configurable> multiplicitiesExclusionFormula{"multiplicitiesExclusionFormula", {multiplicityCentralityCorrelationsFormulaBase[0], 11, 1, {SYSTEMNAME(0), SYSTEMNAME(1), SYSTEMNAME(2), SYSTEMNAME(3), SYSTEMNAME(4), SYSTEMNAME(5), SYSTEMNAME(6), SYSTEMNAME(7), SYSTEMNAME(8), SYSTEMNAME(9), SYSTEMNAME(10)}, {"Exclusion formula"}}, "Formula for excluding outliers of the multiplicities correlations. Use any parameter from centMultCorrelationsParamsMap"}; + Configurable triggSel{"triggSel", "mb+nocollintrstd+nocollinrofstd+nosamebunchpup+isvtxitstpc+gooditslayerall", "Trigger selection: check \'triggerSelectionBitsMap\' for options. Default: mb+nocollintrstd+nocollinrofstd+nosamebunchpup+isvtxitstpc+gooditslayerall"}; struct : ConfigurableGroup { std::string prefix = "cfgEventSelection.occupancySelection"; Configurable occupancyEstimation{"occupancyEstimation", "None", "Occupancy estimation: None, Tracks, FT0C. Default None"}; @@ -424,7 +517,6 @@ struct DptDptFilter { } cfgEventSelection; Configurable cfgSystem{"cfgSystem", "PbPb", "System: Auto, pp, PbPb, Pbp, pPb, XeXe, ppRun3, PbPbRun3. Default PbPb"}; Configurable cfgDataType{"cfgDataType", "data", "Data type: data, datanoevsel, MC, FastMC, OnTheFlyMC. Default data"}; - Configurable cfgTriggSel{"cfgTriggSel", "MB", "Trigger selection: MB,VTXTOFMATCHED,VTXTRDMATCHED,VTXTRDTOFMATCHED,None. Default MB"}; Configurable cfgCentSpec{"cfgCentSpec", "00-10,10-20,20-30,30-40,40-50,50-60,60-70,70-80", "Centrality/multiplicity ranges in min-max separated by commas"}; Configurable cfgOverallMinP{"cfgOverallMinP", 0.0f, "The overall minimum momentum for the analysis. Default: 0.0"}; struct : ConfigurableGroup { @@ -448,6 +540,7 @@ struct DptDptFilter { Produces gencollisionsinfo; Multiplicity multiplicity; + Preslice perCollision = aod::track::collisionId; void init(InitContext const&) { @@ -475,7 +568,7 @@ struct DptDptFilter { } else if (doprocessOnTheFlyGeneratorLevel) { fCentMultEstimator = CentMultFV0A; } else { - fCentMultEstimator = getCentMultEstimator(cfgCentMultEstimator); + fCentMultEstimator = getCentMultEstimator(cfgCentMultEstimator.value.c_str()); } /* RCT information usage */ if (cfgEventSelection.rctSource.value == "None") { @@ -487,19 +580,22 @@ struct DptDptFilter { } /* the occupancy selection */ - fOccupancyEstimation = getOccupancyEstimator(cfgEventSelection.occupancySelection.occupancyEstimation); + fOccupancyEstimation = getOccupancyEstimator(cfgEventSelection.occupancySelection.occupancyEstimation.value.c_str()); fMinOccupancy = cfgEventSelection.occupancySelection.minOccupancy; fMaxOccupancy = cfgEventSelection.occupancySelection.maxOccupancy; /* the trigger selection */ - triggerSelectionFlags = getTriggerSelection(cfgTriggSel); + triggerSelectionFlags = getTriggerSelection(cfgEventSelection.triggSel.value.c_str()); traceCollId0 = cfgTraceCollId0; /* if the system type is not known at this time, we have to put the initialization somewhere else */ - fSystem = getSystemType(cfgSystem); + fSystem = getSystemType(cfgSystem.value.c_str()); fLhcRun = multRunForSystemMap.at(fSystem); fDataType = getDataType(cfgDataType); + /* the multiplicities outliers exclusion */ + multiplicityCentralityCorrelationsExclusion = getExclusionFormula(cfgEventSelection.multiplicitiesExclusionFormula->getData()[fSystem][0].c_str()); + /* create the output list which will own the task histograms */ TList* fOutputList = new TList(); fOutputList->SetOwner(true); @@ -509,18 +605,18 @@ struct DptDptFilter { /* create the reconstructed data histograms */ fhEventSelection = new TH1D("EventSelection", ";;counts", CollSelNOOFFLAGS, -0.5f, static_cast(CollSelNOOFFLAGS) - 0.5f); for (int ix = 0; ix < CollSelNOOFFLAGS; ++ix) { - fhEventSelection->GetXaxis()->SetBinLabel(ix + 1, collisionSelectionExternalNamesMap.at(ix).c_str()); + fhEventSelection->GetXaxis()->SetBinLabel(ix + 1, collisionSelectionExternalNamesMap.at(ix).data()); } fhTriggerSelection = new TH1D("TriggerSelection", ";;counts", TriggSelNOOFTRIGGERS, -0.5f, static_cast(TriggSelNOOFTRIGGERS) - 0.5f); for (int ix = 0; ix < TriggSelNOOFTRIGGERS; ++ix) { - fhTriggerSelection->GetXaxis()->SetBinLabel(ix + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ix) ? 2 : 1, triggerSelectionExternalNamesMap.at(ix).c_str()).Data()); + fhTriggerSelection->GetXaxis()->SetBinLabel(ix + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ix) ? 2 : 1, triggerSelectionExternalNamesMap.at(ix).data()).Data()); } fhTriggerSelectionCorrelations = new TH2D("TriggerSelectionCorrelations", ";;;counts", TriggSelNOOFTRIGGERS, -0.5f, static_cast(TriggSelNOOFTRIGGERS) - 0.5f, TriggSelNOOFTRIGGERS, -0.5f, static_cast(TriggSelNOOFTRIGGERS) - 0.5f); for (int ixy = 0; ixy < TriggSelNOOFTRIGGERS; ++ixy) { - fhTriggerSelectionCorrelations->GetXaxis()->SetBinLabel(ixy + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ixy) ? 2 : 1, triggerSelectionExternalNamesMap.at(ixy).c_str()).Data()); - fhTriggerSelectionCorrelations->GetYaxis()->SetBinLabel(ixy + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ixy) ? 2 : 1, triggerSelectionExternalNamesMap.at(ixy).c_str()).Data()); + fhTriggerSelectionCorrelations->GetXaxis()->SetBinLabel(ixy + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ixy) ? 2 : 1, triggerSelectionExternalNamesMap.at(ixy).data()).Data()); + fhTriggerSelectionCorrelations->GetYaxis()->SetBinLabel(ixy + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ixy) ? 2 : 1, triggerSelectionExternalNamesMap.at(ixy).data()).Data()); } fhVertexZB = new TH1F("VertexZB", "Vertex Z; z_{vtx}", 60, -15, 15); @@ -530,32 +626,32 @@ struct DptDptFilter { #define DPTDPTCENTRALITYAXIS 105, -0.5f, 104.5f #define DPTDPTMULTIPLICITYAXIS(est) 1001, -0.5f, cfgEventSelection.multiplicityUpperLimit->getData()[fSystem][est] - 0.5f - std::string multestimator = getCentMultEstimatorName(fCentMultEstimator); + std::string_view multestimator = getCentMultEstimatorName(fCentMultEstimator); fhCentMultB = new TH1F("CentralityB", "Centrality before cut; centrality (%)", DPTDPTCENTRALITYAXIS); fhCentMultA = new TH1F("CentralityA", "Centrality; centrality (%)", DPTDPTCENTRALITYAXIS); - fhMultB = new TH1F("MultB", TString::Format("%s Multiplicity before cut;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), DPTDPTMULTIPLICITYAXIS(estimatorMultiplicitySourceMap.at(fCentMultEstimator))); - fhMultA = new TH1F("MultA", TString::Format("%s Multiplicity;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), DPTDPTMULTIPLICITYAXIS(estimatorMultiplicitySourceMap.at(fCentMultEstimator))); + fhMultB = new TH1F("MultB", TString::Format("%s Multiplicity before cut;%s Multiplicity;Collisions", multestimator.data(), multestimator.data()), DPTDPTMULTIPLICITYAXIS(estimatorMultiplicitySourceMap.at(fCentMultEstimator))); + fhMultA = new TH1F("MultA", TString::Format("%s Multiplicity;%s Multiplicity;Collisions", multestimator.data(), multestimator.data()), DPTDPTMULTIPLICITYAXIS(estimatorMultiplicitySourceMap.at(fCentMultEstimator))); if (cfgEventSelection.fillQc) { /* the quality control histograms */ for (int i = 0; i < BeforeAfterNOOFTIMES; ++i) { - fhMultiplicityVsCentrality[i] = new TH2F(TString::Format("MultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);Number of tracks", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); + fhMultiplicityVsCentrality[i] = new TH2F(TString::Format("MultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);Number of tracks", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); fhMultiplicityVsT0cMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsT0cMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0C Multiplicity;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0C), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); fhMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A Multiplicity;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); fhMultiplicityVsV0aMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsV0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;V0A Multiplicity;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceV0A), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); fhMultiplicityVsPvMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsPvMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;PV contributors;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); - fhPvMultiplicityVsCentrality[i] = new TH2F(TString::Format("PvMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);PV contributors", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); + fhPvMultiplicityVsCentrality[i] = new TH2F(TString::Format("PvMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);PV contributors", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); fhPvMultiplicityVsT0cMultiplicity[i] = new TH2F(TString::Format("PvMultiplicityVsT0cMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0C multiplicity;PV contributors", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0C), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); fhPvMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("PvMultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A multiplicity;PV contributors", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); fhPvMultiplicityVsV0aMultiplicity[i] = new TH2F(TString::Format("PvMultiplicityVsV0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;V0A multiplicity;PV contributors", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceV0A), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); - fhV0aMultiplicityVsCentrality[i] = new TH2F(TString::Format("V0aMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);V0A multiplicity", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); + fhV0aMultiplicityVsCentrality[i] = new TH2F(TString::Format("V0aMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);V0A multiplicity", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); fhV0aMultiplicityVsT0cMultiplicity[i] = new TH2F(TString::Format("V0aMultiplicityVsT0cMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0C multiplicity;V0A multiplicity", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0C), DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); fhV0aMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("V0aMultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A multiplicity;V0A multiplicity", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); - fhT0cMultiplicityVsCentrality[i] = new TH2F(TString::Format("T0cMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);T0C multiplicity", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceT0C)); + fhT0cMultiplicityVsCentrality[i] = new TH2F(TString::Format("T0cMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);T0C multiplicity", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceT0C)); fhT0cMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("T0cMultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A multiplicity;T0C multiplicity", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourceT0C)); - fhT0CentralityVsCentrality[i] = new TH2F(TString::Format("T0CentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);T0 centrality(%%)", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); - fhV0aCentralityVsCentrality[i] = new TH2F(TString::Format("V0aCentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);V0A centrality (%%)", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); - fhNtpvCentralityVsCentrality[i] = new TH2F(TString::Format("NtpvCentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);NTPV centrality (%%)", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); + fhT0CentralityVsCentrality[i] = new TH2F(TString::Format("T0CentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);T0 centrality(%%)", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); + fhV0aCentralityVsCentrality[i] = new TH2F(TString::Format("V0aCentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);V0A centrality (%%)", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); + fhNtpvCentralityVsCentrality[i] = new TH2F(TString::Format("NtpvCentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);NTPV centrality (%%)", beforeAfterName[i].c_str(), multestimator.data()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); } } @@ -643,29 +739,33 @@ struct DptDptFilter { template bool processGenerated(CollisionObject const& mccollision, ParticlesList const& mcparticles, float centormult); - template + template void processGeneratorLevel(aod::McCollision const& mccollision, CollisionsGroup const& collisions, aod::McParticles const& mcparticles, AllCollisions const& allcollisions, + AllTracks const& alltracks, float defaultcent); void processWithCentGeneratorLevel(aod::McCollision const& mccollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcparticles, - aod::CollisionsEvSelCent const& allcollisions); + aod::CollisionsEvSelCent const& allcollisions, + DptDptFullTracksDetLevel const& alltracks); PROCESS_SWITCH(DptDptFilter, processWithCentGeneratorLevel, "Process generated with centrality", false); void processWithRun2CentGeneratorLevel(aod::McCollision const& mccollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcparticles, - aod::CollisionsEvSelRun2Cent const& allcollisions); + aod::CollisionsEvSelRun2Cent const& allcollisions, + DptDptFullTracksDetLevel const& alltracks); PROCESS_SWITCH(DptDptFilter, processWithRun2CentGeneratorLevel, "Process generated with centrality", false); void processWithoutCentGeneratorLevel(aod::McCollision const& mccollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcparticles, - aod::CollisionsEvSel const& allcollisions); + aod::CollisionsEvSel const& allcollisions, + DptDptFullTracksDetLevel const& alltracks); PROCESS_SWITCH(DptDptFilter, processWithoutCentGeneratorLevel, "Process generated without centrality", false); void processOnTheFlyGeneratorLevel(aod::McCollision const& mccollision, @@ -693,6 +793,7 @@ void DptDptFilter::processReconstructed(CollisionObject const& collision, Tracks float centormult = tentativecentmult; int64_t orbit = collision.template bc_as().globalBC() / nBCsPerOrbit; bool withinOrbitOfInterest = (cfgEventSelection.minOrbit <= orbit) && (orbit < cfgEventSelection.maxOrbit); + storeMultiplicitiesAndCentralities(collision, ftracks); if (withinOrbitOfInterest && isEventSelected(collision, centormult)) { acceptedevent = true; fhCentMultA->Fill(centormult); @@ -732,32 +833,46 @@ void DptDptFilter::processReconstructed(CollisionObject const& collision, Tracks } /* report QC information if required */ if (cfgEventSelection.fillQc) { - [&](bool accepted) { - for (int i = 0; i < BeforeAfterNOOFTIMES; ++i) { - fhMultiplicityVsCentrality[i]->Fill(centormult, ftracks.size()); - fhMultiplicityVsT0cMultiplicity[i]->Fill(collision.multFT0C(), ftracks.size()); - fhMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), ftracks.size()); - fhMultiplicityVsV0aMultiplicity[i]->Fill(collision.multFV0A(), ftracks.size()); - fhMultiplicityVsPvMultiplicity[i]->Fill(collision.multNTracksPV(), ftracks.size()); - fhPvMultiplicityVsCentrality[i]->Fill(centormult, collision.multNTracksPV()); - fhPvMultiplicityVsT0cMultiplicity[i]->Fill(collision.multFT0C(), collision.multNTracksPV()); - fhPvMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), collision.multNTracksPV()); - fhPvMultiplicityVsV0aMultiplicity[i]->Fill(collision.multFV0A(), collision.multNTracksPV()); - fhV0aMultiplicityVsCentrality[i]->Fill(centormult, collision.multFV0A()); - fhV0aMultiplicityVsT0cMultiplicity[i]->Fill(collision.multFT0C(), collision.multFV0A()); - fhV0aMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), collision.multFV0A()); - fhT0cMultiplicityVsCentrality[i]->Fill(centormult, collision.multFT0C()); - fhT0cMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), collision.multFT0C()); - if constexpr (framework::has_type_v) { - fhT0CentralityVsCentrality[i]->Fill(centormult, collision.centFT0M()); - fhV0aCentralityVsCentrality[i]->Fill(centormult, collision.centFV0A()); - fhNtpvCentralityVsCentrality[i]->Fill(centormult, collision.centNTPV()); - } - /* if not accepted only before is filled */ - if (!accepted) + auto fillHistograms = [&](int step) { + fhMultiplicityVsCentrality[step]->Fill(centormult, ftracks.size()); + fhMultiplicityVsT0cMultiplicity[step]->Fill(collision.multFT0C(), ftracks.size()); + fhMultiplicityVsT0aMultiplicity[step]->Fill(collision.multFT0A(), ftracks.size()); + fhMultiplicityVsV0aMultiplicity[step]->Fill(collision.multFV0A(), ftracks.size()); + fhMultiplicityVsPvMultiplicity[step]->Fill(collision.multNTracksPV(), ftracks.size()); + fhPvMultiplicityVsCentrality[step]->Fill(centormult, collision.multNTracksPV()); + fhPvMultiplicityVsT0cMultiplicity[step]->Fill(collision.multFT0C(), collision.multNTracksPV()); + fhPvMultiplicityVsT0aMultiplicity[step]->Fill(collision.multFT0A(), collision.multNTracksPV()); + fhPvMultiplicityVsV0aMultiplicity[step]->Fill(collision.multFV0A(), collision.multNTracksPV()); + fhV0aMultiplicityVsCentrality[step]->Fill(centormult, collision.multFV0A()); + fhV0aMultiplicityVsT0cMultiplicity[step]->Fill(collision.multFT0C(), collision.multFV0A()); + fhV0aMultiplicityVsT0aMultiplicity[step]->Fill(collision.multFT0A(), collision.multFV0A()); + fhT0cMultiplicityVsCentrality[step]->Fill(centormult, collision.multFT0C()); + fhT0cMultiplicityVsT0aMultiplicity[step]->Fill(collision.multFT0A(), collision.multFT0C()); + if constexpr (framework::has_type_v) { + fhT0CentralityVsCentrality[step]->Fill(centormult, collision.centFT0M()); + fhV0aCentralityVsCentrality[step]->Fill(centormult, collision.centFV0A()); + fhNtpvCentralityVsCentrality[step]->Fill(centormult, collision.centNTPV()); + } + }; + for (int i = 0; i < BeforeAfterNOOFTIMES; ++i) { + switch (static_cast(i)) { + case BeforeAfterBEFORE: + fillHistograms(i); + break; + case BeforeAfterBEFOREMULTCORR: + if ((collisionFlags & CollSelPREMULTACCEPTEDRUN3) == CollSelPREMULTACCEPTEDRUN3) { + fillHistograms(i); + } + break; + case BeforeAfterAFTER: + if (acceptedevent) { + fillHistograms(i); + } + break; + default: break; } - }(acceptedevent); + } } } @@ -813,11 +928,12 @@ bool DptDptFilter::processGenerated(CollisionObject const& mccollision, Particle return static_cast(acceptedevent); } -template +template void DptDptFilter::processGeneratorLevel(aod::McCollision const& mccollision, CollisionsGroup const& collisions, aod::McParticles const& mcparticles, AllCollisions const& allcollisions, + AllTracks const& alltracks, float defaultcent) { using namespace dptdptfilter; @@ -833,6 +949,8 @@ void DptDptFilter::processGeneratorLevel(aod::McCollision const& mccollision, if (tmpcollision.has_mcCollision()) { if (tmpcollision.mcCollisionId() == mccollision.globalIndex()) { typename AllCollisions::iterator const& collision = allcollisions.iteratorAt(tmpcollision.globalIndex()); + auto collisionTracks = alltracks.sliceBy(perCollision, collision.globalIndex()); + storeMultiplicitiesAndCentralities(collision, collisionTracks); if (isEventSelected(collision, defaultcent)) { if (processGenerated(mccollision, mcparticles, defaultcent)) { fhTrueVertexZAA->Fill((mccollision.posZ())); @@ -851,25 +969,28 @@ void DptDptFilter::processGeneratorLevel(aod::McCollision const& mccollision, void DptDptFilter::processWithCentGeneratorLevel(aod::McCollision const& mccollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcparticles, - aod::CollisionsEvSelCent const& allcollisions) + aod::CollisionsEvSelCent const& allcollisions, + DptDptFullTracksDetLevel const& alltracks) { - processGeneratorLevel(mccollision, collisions, mcparticles, allcollisions, 50.0); + processGeneratorLevel(mccollision, collisions, mcparticles, allcollisions, alltracks, 50.0); } void DptDptFilter::processWithRun2CentGeneratorLevel(aod::McCollision const& mccollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcparticles, - aod::CollisionsEvSelRun2Cent const& allcollisions) + aod::CollisionsEvSelRun2Cent const& allcollisions, + DptDptFullTracksDetLevel const& alltracks) { - processGeneratorLevel(mccollision, collisions, mcparticles, allcollisions, 50.0); + processGeneratorLevel(mccollision, collisions, mcparticles, allcollisions, alltracks, 50.0); } void DptDptFilter::processWithoutCentGeneratorLevel(aod::McCollision const& mccollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcparticles, - aod::CollisionsEvSel const& allcollisions) + aod::CollisionsEvSel const& allcollisions, + DptDptFullTracksDetLevel const& alltracks) { - processGeneratorLevel(mccollision, collisions, mcparticles, allcollisions, 50.0); + processGeneratorLevel(mccollision, collisions, mcparticles, allcollisions, alltracks, 50.0); } void DptDptFilter::processOnTheFlyGeneratorLevel(aod::McCollision const& mccollision, @@ -921,7 +1042,6 @@ T computeRMS(std::vector& vec) } struct DptDptFilterTracks { - Produces scannedtracks; Produces tracksinfo; Produces scannedgentracks; diff --git a/PWGCF/TableProducer/dptDptFilter.h b/PWGCF/TableProducer/dptDptFilter.h index d99ae8951d8..14a49c3bbf0 100644 --- a/PWGCF/TableProducer/dptDptFilter.h +++ b/PWGCF/TableProducer/dptDptFilter.h @@ -34,10 +34,13 @@ #include #include +#include #include #include #include +#include + #include #include #include @@ -47,6 +50,7 @@ #include #include #include +#include #include namespace o2 @@ -84,7 +88,7 @@ enum SystemType { /// \std::map systemInternalCodesMap /// \brief maps system names to internal system codes -static const std::map systemInternalCodesMap{ +static const std::map systemInternalCodesMap{ {"", SystemNoSystem}, {"pp", SystemPp}, {"pPb", SystemPPb}, @@ -99,7 +103,7 @@ static const std::map systemInternalCodesMap{ /// \std::map systemExternalNamesMap /// \brief maps system internal codes to system external names -static const std::map systemExternalNamesMap{ +static const std::map systemExternalNamesMap{ {SystemNoSystem, ""}, {SystemPp, "pp"}, {SystemPPb, "pPb"}, @@ -140,7 +144,7 @@ enum CentMultEstimatorType { /// \std::map estimatorInternalCodesMap /// \brief maps centrality/multiplicity estimator names to internal estimator codes -static const std::map estimatorInternalCodesMap{ +static const std::map estimatorInternalCodesMap{ {"NOCM", CentMultNOCM}, {"V0M", CentMultV0M}, {"CL0", CentMultCL0}, @@ -153,7 +157,7 @@ static const std::map estimatorInternalCodesMap{ /// \std::map estimatorExternalNamesMap /// \brief maps internal estimator codes to centrality/multiplicity estimator external names -static const std::map estimatorExternalNamesMap{ +static const std::map estimatorExternalNamesMap{ {CentMultNOCM, "NOCM"}, {CentMultV0M, "V0M"}, {CentMultCL0, "CL0"}, @@ -216,7 +220,7 @@ static const std::map estimatorMultiplicitySourceMap{ /// \std::vector multiplicitySourceExternalNamesMap /// \brief maps internal multiplicity source to external names for the LHC runs -static const std::vector> multiplicitySourceExternalNamesMap{ +static const std::vector> multiplicitySourceExternalNamesMap{ /* Run 1 and Run 2 */ { {MultSourceT0A, "T0A multiplicity"}, @@ -225,7 +229,7 @@ static const std::vector> multiplicitySourceExternalN {MultSourceV0A, "V0A multiplicity"}, {MultSourceV0C, "V0C multiplicity"}, {MultSourceV0M, "V0M multiplicity"}, - {MultSourceNtracks, "Number of tracks"}, + {MultSourceNtracks, "Global tracks"}, {MultSourcePvContributors, "PV contributors"}}, /* Run 3 */ { @@ -235,22 +239,94 @@ static const std::vector> multiplicitySourceExternalN {MultSourceV0A, "FV0A multiplicity"}, {MultSourceV0C, "WRONG SOURCE"}, {MultSourceV0M, "FV0M multiplicity"}, - {MultSourceNtracks, "Number of tracks"}, + {MultSourceNtracks, "Global tracks"}, {MultSourcePvContributors, "PV contributors"}}}; /// \std::map multiplicitySourceConfigNamesMap /// \brief maps internal multiplicity source to external configuration names /// At configuration time neither the system nor the lhc run is known -static const std::map multiplicitySourceConfigNamesMap{ - {MultSourceT0A, "FT0A"}, - {MultSourceT0C, "FT0C"}, - {MultSourceT0M, "FT0M"}, - {MultSourceV0A, "FV0A"}, - {MultSourceV0C, "V0C"}, - {MultSourceV0M, "FV0M"}, - {MultSourceNtracks, "Number of tracks"}, +static const std::map multiplicitySourceConfigNamesMap{ + {MultSourceT0A, "FT0A (T0A)"}, + {MultSourceT0C, "FT0C (T0C)"}, + {MultSourceT0M, "FT0M (T0M)"}, + {MultSourceV0A, "FV0A (V0A)"}, + {MultSourceV0C, "WRONG (V0C)"}, + {MultSourceV0M, "FV0M (V0M)"}, + {MultSourceNtracks, "Global tracks"}, {MultSourcePvContributors, "PV contributors"}}; +/// \enum CentMultCorrelationsParams +/// \brief internal codes for the supported parameters for centrality/multiplicity correlations exclusion cuts +enum CentMultCorrelationsParams { + CentMultCorrelationsMT0A = 0, ///< multiplicity from T0A + CentMultCorrelationsMT0C, ///< multiplicity from T0C + CentMultCorrelationsMT0M, ///< multiplicity from T0M + CentMultCorrelationsMV0A, ///< multiplicity from V0A + CentMultCorrelationsMV0C, ///< multiplicity from V0C (only Run 1 & Run 2) + CentMultCorrelationsMV0M, ///< multiplicity from V0M + CentMultCorrelationsMNGLTRK, ///< multiplicity from number of global tracks + CentMultCorrelationsMNPVC, ///< multiplicity from number of PV contributors + CentMultCorrelationsCT0A, ///< centrality from T0A + CentMultCorrelationsCT0C, ///< centrality from T0C + CentMultCorrelationsCT0M, ///< centrality from T0M + CentMultCorrelationsCV0A, ///< centrality from V0A + CentMultCorrelationsCNTPV, ///< centrality from number of PV contributors + CentMultCorrelationsNOOFPARAMS ///< the number of parameters supported +}; + +/// @brief prefix increment operator +/// @param ipar value +/// @return the incremented value +inline CentMultCorrelationsParams& operator++(CentMultCorrelationsParams& ipar) +{ + return ipar = static_cast(static_cast(ipar) + 1); +} + +/// @brief postfix increment operator +/// @param ipar the value +/// @param empty +/// @return the same value +inline CentMultCorrelationsParams operator++(CentMultCorrelationsParams& ipar, int) +{ + CentMultCorrelationsParams iparTmp(ipar); + ++ipar; + return iparTmp; +} + +/// \std::map centMultCorrelationsParamsMap +/// \brief maps centrality/multiplicity correlations parameters names to internal codes +static const std::map centMultCorrelationsParamsMap{ + {"MT0A", CentMultCorrelationsMT0A}, + {"MT0C", CentMultCorrelationsMT0C}, + {"MT0M", CentMultCorrelationsMT0M}, + {"MV0A", CentMultCorrelationsMV0A}, + {"MV0C", CentMultCorrelationsMV0C}, + {"MV0M", CentMultCorrelationsMV0M}, + {"MNGLTRK", CentMultCorrelationsMNGLTRK}, + {"MNPVC", CentMultCorrelationsMNPVC}, + {"CT0A", CentMultCorrelationsCT0A}, + {"CT0C", CentMultCorrelationsCT0C}, + {"CT0M", CentMultCorrelationsCT0M}, + {"CV0A", CentMultCorrelationsCV0A}, + {"CNTPV", CentMultCorrelationsCNTPV}}; + +/// \std::map centMultCorrelationsParamsNamesMap +/// \brief maps centrality/multiplicity correlations parameters internal codes to their external names +static const std::map centMultCorrelationsParamsNamesMap{ + {CentMultCorrelationsMT0A, "MT0A"}, + {CentMultCorrelationsMT0C, "MT0C"}, + {CentMultCorrelationsMT0M, "MT0M"}, + {CentMultCorrelationsMV0A, "MV0A"}, + {CentMultCorrelationsMV0C, "MV0C"}, + {CentMultCorrelationsMV0M, "MV0M"}, + {CentMultCorrelationsMNGLTRK, "MNGLTRK"}, + {CentMultCorrelationsMNPVC, "MNPVC"}, + {CentMultCorrelationsCT0A, "CT0A"}, + {CentMultCorrelationsCT0C, "CT0C"}, + {CentMultCorrelationsCT0M, "CT0M"}, + {CentMultCorrelationsCV0A, "CV0A"}, + {CentMultCorrelationsCNTPV, "CNTPV"}}; + /// \enum TriggerSelectionTags /// \brief The potential trigger tags to apply for event selection enum TriggerSelectionTags { @@ -275,7 +351,7 @@ enum TriggerSelectionTags { /// \std::map triggerSelectionBitsMap /// \brief maps trigger selection tags to internal trigger selection bits -static const std::map triggerSelectionBitsMap{ +static const std::map triggerSelectionBitsMap{ {"none", TriggSelNONE}, {"mb", TriggSelMB}, {"nosamebunchpup", TriggSelNOSAMEBUNCHPUP}, @@ -295,7 +371,7 @@ static const std::map triggerSelectionBitsMap{ /// \std::map triggerSelectionExternalNamesMap /// \brief maps trigger selection bits to external names -static const std::map triggerSelectionExternalNamesMap{ +static const std::map triggerSelectionExternalNamesMap{ {TriggSelNONE, "none"}, {TriggSelMB, "Sel8"}, ///< Sel8 includes kIsTriggerTVX, kNoTimeFrameBorder, and kNoITSROFrameBorder {TriggSelNOSAMEBUNCHPUP, "No same bunch pileup"}, @@ -325,22 +401,26 @@ enum OccupancyEstimationType { /// \enum CollisionSelectionFlags /// \brief The different criteria for selecting/rejecting collisions enum CollisionSelectionFlags { - CollSelIN = 0, ///< new unhandled, yet, event - CollSelMBBIT, ///< minimum bias - CollSelINT7BIT, ///< INT7 Run 1/2 - CollSelSEL7BIT, ///< Sel7 Run 1/2 - CollSelTRIGGSELBIT, ///< Accepted by trigger selection - CollSelRCTBIT, ///< Accetped by the RCT information - CollSelOCCUPANCYBIT, ///< occupancy within limits - CollSelCENTRALITYBIT, ///< centrality cut passed - CollSelZVERTEXBIT, ///< zvtx cut passed - CollSelSELECTED, ///< the event has passed all selections - CollSelNOOFFLAGS ///< number of flags + CollSelIN = 0, ///< new unhandled, yet, event + CollSelMBBIT, ///< minimum bias + CollSelINT7BIT, ///< INT7 Run 1/2 + CollSelSEL7BIT, ///< Sel7 Run 1/2 + CollSelTRIGGSELBIT, ///< Accepted by trigger selection + CollSelRCTBIT, ///< Accetped by the RCT information + CollSelOCCUPANCYBIT, ///< occupancy within limits + CollSelCENTRALITYBIT, ///< centrality cut passed + CollSelZVERTEXBIT, ///< zvtx cut passed + CollSelMULTCORRELATIONS, ///< multiplicities correlations passed + CollSelSELECTED, ///< the event has passed all selections + CollSelNOOFFLAGS ///< number of flags }; +constexpr std::bitset<32> CollSelACCEPTEDRUN3 = BIT(CollSelTRIGGSELBIT) | BIT(CollSelRCTBIT) | BIT(CollSelOCCUPANCYBIT) | BIT(CollSelCENTRALITYBIT) | BIT(CollSelZVERTEXBIT) | BIT(CollSelMULTCORRELATIONS); +constexpr std::bitset<32> CollSelPREMULTACCEPTEDRUN3 = BIT(CollSelTRIGGSELBIT) | BIT(CollSelRCTBIT) | BIT(CollSelOCCUPANCYBIT) | BIT(CollSelCENTRALITYBIT) | BIT(CollSelZVERTEXBIT); + /// \std::mag collisionSelectionExternalNamesMap /// \brief maps collision selection bits to external names -static const std::map collisionSelectionExternalNamesMap{ +static const std::map collisionSelectionExternalNamesMap{ {CollSelIN, "In"}, {CollSelMBBIT, "MB"}, {CollSelINT7BIT, "INT7"}, @@ -350,6 +430,7 @@ static const std::map collisionSelectionExternalNamesMap{ {CollSelOCCUPANCYBIT, "Occupancy"}, {CollSelCENTRALITYBIT, "Centrality"}, {CollSelZVERTEXBIT, "z vertex"}, + {CollSelMULTCORRELATIONS, "Multiplicities correlations"}, {CollSelSELECTED, "Selected"}}; /// \enum StrongDebugging @@ -385,6 +466,14 @@ std::bitset<32> collisionSelectionFlags; std::bitset<32> triggerFlags; std::bitset<32> triggerSelectionFlags; +//============================================================================================ +// The collision exclusion using correlations between multiplicity/centrality observables +//============================================================================================ +bool useCentralityMultiplicityCorrelationsExclusion = false; +std::vector collisionMultiplicityCentralityObservables = {}; +std::vector observableIndexForCentralityMultiplicityParameter = {}; +TFormula* multiplicityCentralityCorrelationsExclusion = nullptr; + //============================================================================================ // The input data metadata access helper //============================================================================================ @@ -736,17 +825,17 @@ float particleMaxDCAxy = 999.9f; float particleMaxDCAZ = 999.9f; bool traceCollId0 = false; -inline std::bitset<32> getTriggerSelection(std::string const& triggstr) +inline std::bitset<32> getTriggerSelection(std::string_view const& triggstr) { std::bitset<32> flags; auto split = [](const auto s) { - std::vector tokens; - std::string token; + std::vector tokens; + std::string_view token; size_t posStart = 0; size_t posEnd; - while ((posEnd = s.find("+", posStart)) != std::string::npos) { + while ((posEnd = s.find("+", posStart)) != std::string_view::npos) { token = s.substr(posStart, posEnd - posStart); posStart = posEnd + 1; tokens.push_back(token); @@ -755,13 +844,13 @@ inline std::bitset<32> getTriggerSelection(std::string const& triggstr) return tokens; }; - std::vector tags = split(triggstr); + std::vector tags = split(triggstr); for (const auto& tag : tags) { if (triggerSelectionBitsMap.contains(tag)) { flags.set(triggerSelectionBitsMap.at(tag), true); } else { - LOGF(fatal, "Wrong trigger selection tag: %s", tag.c_str()); + LOGF(fatal, "Wrong trigger selection tag: %s", tag.data()); } } return flags; @@ -770,15 +859,16 @@ inline std::bitset<32> getTriggerSelection(std::string const& triggstr) inline SystemType getSytemTypeFromMetaData() { auto period = metadataInfo.get("LPMProductionTag"); + auto anchoredPeriod = metadataInfo.get("AnchorProduction"); - if (period == "LHC25ad" || period == "LHC25g5") { - LOGF(info, "Configuring for p-O LHC25ad period"); + if (period == "LHC25ad" || anchoredPeriod == "LHC25ad") { + LOGF(info, "Configuring for p-O (anchored to) LHC25ad period"); return SystemPORun3; - } else if (period == "LHC25ae" || period == "LHC25g6") { - LOGF(info, "Configuring for O-O LHC25ae period"); + } else if (period == "LHC25ae" || anchoredPeriod == "LHC25ae") { + LOGF(info, "Configuring for O-O (anchored to) LHC25ae period"); return SystemOORun3; - } else if (period == "LHC25af" || period == "LHC25g7") { - LOGF(info, "Configuring for Ne-Ne LHC25af period"); + } else if (period == "LHC25af" || anchoredPeriod == "LHC25af") { + LOGF(info, "Configuring for Ne-Ne (anchored to) LHC25af period"); return SystemNeNeRun3; } else { LOGF(fatal, "DptDptCorrelations::getSystemTypeFromMetadata(). No automatic system type configuration for %s period", period.c_str()); @@ -786,7 +876,7 @@ inline SystemType getSytemTypeFromMetaData() return SystemPbPb; } -inline SystemType getSystemType(std::string const& sysstr) +inline SystemType getSystemType(std::string_view const& sysstr) { /* we have to figure out how extract the system type */ if (sysstr == "Auto") { @@ -797,7 +887,7 @@ inline SystemType getSystemType(std::string const& sysstr) if (systemInternalCodesMap.contains(sysstr)) { return static_cast(systemInternalCodesMap.at(sysstr)); } else { - LOGF(fatal, "DptDptCorrelations::getSystemType(). Wrong system type: %s", sysstr.c_str()); + LOGF(fatal, "DptDptCorrelations::getSystemType(). Wrong system type: %s", sysstr.data()); } } return SystemPbPb; @@ -825,17 +915,17 @@ inline DataType getDataType(std::string const& datastr) return kData; } -inline CentMultEstimatorType getCentMultEstimator(std::string const& datastr) +inline CentMultEstimatorType getCentMultEstimator(std::string_view const& datastr) { if (estimatorInternalCodesMap.contains(datastr)) { return static_cast(estimatorInternalCodesMap.at(datastr)); } else { - LOGF(fatal, "Centrality/Multiplicity estimator %s not supported yet", datastr.c_str()); + LOGF(fatal, "Centrality/Multiplicity estimator %s not supported yet", datastr.data()); } return CentMultNOCM; } -inline std::string getCentMultEstimatorName(CentMultEstimatorType est) +inline std::string_view getCentMultEstimatorName(CentMultEstimatorType est) { if (estimatorExternalNamesMap.contains(est)) { return estimatorExternalNamesMap.at(est); @@ -845,7 +935,7 @@ inline std::string getCentMultEstimatorName(CentMultEstimatorType est) return "WRONG"; } -inline OccupancyEstimationType getOccupancyEstimator(const std::string& estimator) +inline OccupancyEstimationType getOccupancyEstimator(const std::string_view& estimator) { if (estimator == "None") { return OccupancyNOOCC; @@ -854,11 +944,38 @@ inline OccupancyEstimationType getOccupancyEstimator(const std::string& estimato } else if (estimator == "FT0C") { return OccupancyFT0COCC; } else { - LOGF(fatal, "Occupancy estimator %s not supported yet", estimator.c_str()); + LOGF(fatal, "Occupancy estimator %s not supported yet", estimator.data()); return OccupancyNOOCC; } } +/// @brief gets the exclusion formula from the corresponding expression and initializes the exclusion machinery +/// @param std::string_view with the formula expression +/// @return the expression TFormula +inline TFormula* getExclusionFormula(std::string_view formula) +{ + if (formula.length() != 0) { + useCentralityMultiplicityCorrelationsExclusion = true; + TFormula* f = new TFormula("Exclussion expression", formula.data()); + int nParameters = f->GetNpar(); + collisionMultiplicityCentralityObservables.resize(CentMultCorrelationsNOOFPARAMS); + observableIndexForCentralityMultiplicityParameter.resize(nParameters); + LOGF(info, "Configuring outliers exclusion with the formula %s which has %d parameters", formula.data(), nParameters); + for (int iPar = 0; iPar < nParameters; ++iPar) { + if (centMultCorrelationsParamsMap.contains(std::string(f->GetParName(iPar)))) { + observableIndexForCentralityMultiplicityParameter[iPar] = centMultCorrelationsParamsMap.at(std::string(f->GetParName(iPar))); + LOGF(info, "\tAssigned observable %s with index %d to the parameter %s with parameter index %d", centMultCorrelationsParamsNamesMap.at(centMultCorrelationsParamsMap.at(std::string(f->GetParName(iPar)))).data(), static_cast(centMultCorrelationsParamsMap.at(std::string(f->GetParName(iPar)))), f->GetParName(iPar), iPar); + } else { + LOGF(fatal, "Exclusion expression contains parameter %s which is still not supported. Please, fix it!", f->GetParName(iPar)); + } + } + return f; + } else { + useCentralityMultiplicityCorrelationsExclusion = false; + return nullptr; + } +} + ////////////////////////////////////////////////////////////////////////////////// /// Trigger selection ////////////////////////////////////////////////////////////////////////////////// @@ -1172,6 +1289,29 @@ inline bool centralitySelection(aod::McCollision const&, float } } +/// @brief evalues the exclusion formula for the current multiplicity / centrality parameters +/// @return true if the collision is not excluded according to the formula false otherwise +/// WARNING: it has always to be called after filling the multiplicity / centrality observables +/// NOTE: for MC generator level does nothing, as expected +template +inline bool isCollisionNotExcluded() +{ + bool notExcluded = true; + if constexpr (!framework::has_type_v) { + if (useCentralityMultiplicityCorrelationsExclusion) { + [&]() { + /* set the formula parameter values */ + for (size_t iPar = 0; iPar < observableIndexForCentralityMultiplicityParameter.size(); ++iPar) { + multiplicityCentralityCorrelationsExclusion->SetParameter(iPar, collisionMultiplicityCentralityObservables[observableIndexForCentralityMultiplicityParameter[iPar]]); + } + }(); + notExcluded = multiplicityCentralityCorrelationsExclusion->Eval() != 0; + } + } + collisionFlags.set(CollSelMULTCORRELATIONS, notExcluded); + return notExcluded; +} + ////////////////////////////////////////////////////////////////////////////////// /// Occupancy selection ////////////////////////////////////////////////////////////////////////////////// @@ -1274,20 +1414,22 @@ inline bool isEventSelected(CollisionObject const& collision, float& centormult) bool trigsel = triggerSelection(collision); - bool rctsel = false; + /* run condition table information */ + bool rctsel = true; if (useRctInformation) { - if constexpr (framework::has_type_v) { - if (rctChecker.checkTable(collision)) { - rctsel = true; - collisionFlags.set(CollSelRCTBIT); - } + if constexpr (framework::has_type_v) { + /* RCT condition not considered for generator level */ } else { - LOGF(fatal, "RCT check required but the dataset does not have RCT information associated. Please, fix it"); + if constexpr (framework::has_type_v) { + if (!rctChecker.checkTable(collision)) { + rctsel = false; + } + } else { + LOGF(fatal, "RCT check required but the dataset does not have RCT information associated. Please, fix it"); + } } - } else { - collisionFlags.set(CollSelRCTBIT); - rctsel = true; } + collisionFlags.set(CollSelRCTBIT, rctsel); bool occupancysel = occupancySelection(collision); @@ -1308,7 +1450,9 @@ inline bool isEventSelected(CollisionObject const& collision, float& centormult) bool centmultsel = centralitySelection(collision, centormult); - bool accepted = trigsel && rctsel && occupancysel && zvtxsel && centmultsel; + bool centmultexclusion = isCollisionNotExcluded(); + + bool accepted = trigsel && rctsel && occupancysel && zvtxsel && centmultsel && centmultexclusion; if (accepted) { collisionFlags.set(CollSelSELECTED); diff --git a/PWGCF/Tasks/correlations.cxx b/PWGCF/Tasks/correlations.cxx index 2a6101a5b9a..5122b9ebf64 100644 --- a/PWGCF/Tasks/correlations.cxx +++ b/PWGCF/Tasks/correlations.cxx @@ -182,6 +182,7 @@ struct CorrelationTask { if (doprocessSame2Prong2Prong || doprocessSame2Prong2ProngML) { registry.add("invMassTwoPart", "2D 2-prong invariant mass (GeV/c^2)", {HistType::kTHnSparseF, {axisSpecMass, axisSpecMass, axisPtTrigger, axisPtAssoc, axisMultiplicity}}); registry.add("invMassTwoPartDPhi", "2D 2-prong invariant mass (GeV/c^2)", {HistType::kTHnSparseF, {axisSpecMass, axisSpecMass, axisPtTrigger, axisPtAssoc, axisDeltaPhi}}); + registry.add("invMassTwoPartDEta", "2D 2-prong invariant mass (GeV/c^2)", {HistType::kTHnSparseF, {axisSpecMass, axisSpecMass, axisPtTrigger, axisPtAssoc, axisDeltaEta}}); } } if (doprocessSameDerivedMultSet) { @@ -394,6 +395,9 @@ struct CorrelationTask { continue; registry.fill(HIST("invMassTwoPart"), track1.invMass(), track2.invMass(), track1.pt(), track2.pt(), multiplicity); registry.fill(HIST("invMassTwoPartDPhi"), track1.invMass(), track2.invMass(), track1.pt(), track2.pt(), TVector2::Phi_0_2pi(track1.phi() - track2.phi() + TMath::Pi() / 2.0) - TMath::Pi() / 2.0); + if (std::abs(track1.phi() - track2.phi()) < constants::math::PI * 0.5) { + registry.fill(HIST("invMassTwoPartDEta"), track1.invMass(), track2.invMass(), track1.pt(), track2.pt(), track1.eta() - track2.eta()); + } } } } @@ -637,7 +641,7 @@ struct CorrelationTask { continue; // skip particles that do not match the decay mask } if (cfgV0RapidityMax > 0) { - auto [t, y] = getV0Rapidity(track1); + auto [t, y] = getV0Rapidity(track2); if (t && std::abs(y) > cfgV0RapidityMax) continue; // V0s are not allowed to be outside the rapidity range } diff --git a/PWGCF/Tasks/dptDptCorrelations.cxx b/PWGCF/Tasks/dptDptCorrelations.cxx index 07754ef5316..ffe62250ca9 100644 --- a/PWGCF/Tasks/dptDptCorrelations.cxx +++ b/PWGCF/Tasks/dptDptCorrelations.cxx @@ -971,10 +971,10 @@ struct DptDptCorrelations { nNoOfDimensions = static_cast(cfgNoOfDimensions.value); /* self configure the CCDB access to the input file */ - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBUrl", cfgCCDBUrl, false); - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBPathName", cfgCCDBPathName, false); - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBDate", cfgCCDBDate, false); - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBPeriod", cfgCCDBPeriod, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.url", cfgCCDBUrl, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.pathName", cfgCCDBPathName, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.date", cfgCCDBDate, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.period", cfgCCDBPeriod, false); loadfromccdb = cfgCCDBPathName.length() > 0; /* update the potential binning change */ diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 20a4c7c548f..ee152f11b6b 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -1476,34 +1476,6 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } } - //--------------------------------------------------------------------------------------- - // NOTE: Below there are several TPC pid cuts used for studies of the dE/dx degradation - // and its impact on the high lumi pp quarkonia triggers - // To be removed when not needed anymore - if (!nameStr.compare("jpsiPID1Randomized")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); // standard kine cuts usually are applied via Filter in the task - cut->AddCut(GetAnalysisCut("electronStandardQuality")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - cut->AddCut(GetAnalysisCut("electronPID1randomized")); - return cut; - } - - if (!nameStr.compare("jpsiPID2Randomized")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQuality")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - cut->AddCut(GetAnalysisCut("electronPID2randomized")); - return cut; - } - - if (!nameStr.compare("jpsiPIDnsigmaRandomized")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQuality")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaRandomized")); - return cut; - } - if (!nameStr.compare("jpsiPIDworseRes")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); @@ -5136,13 +5108,6 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPID1randomized")) { - cutLow1->SetParameters(130., -40.0); - cut->AddCut(VarManager::kTPCsignalRandomized, 70., 100.); - cut->AddCut(VarManager::kTPCsignalRandomized, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); - return cut; - } - if (!nameStr.compare("electronPID2")) { cutLow1->SetParameters(130., -40.0); cut->AddCut(VarManager::kTPCsignal, 73., 100.); @@ -5157,13 +5122,6 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPID2randomized")) { - cutLow1->SetParameters(130., -40.0); - cut->AddCut(VarManager::kTPCsignalRandomized, 73., 100.); - cut->AddCut(VarManager::kTPCsignalRandomized, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); - return cut; - } - if (!nameStr.compare("electronPIDnsigma")) { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 3000.0); @@ -5645,13 +5603,6 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDnsigmaRandomized")) { - cut->AddCut(VarManager::kTPCnSigmaElRandomized, -3.0, 3.0); - cut->AddCut(VarManager::kTPCnSigmaPrRandomized, 3.0, 3000.0); - cut->AddCut(VarManager::kTPCnSigmaPiRandomized, 3.0, 3000.0); - return cut; - } - if (!nameStr.compare("electronPIDworseRes")) { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0 * 0.8, 3000.0); // emulates a 20% degradation in PID resolution diff --git a/PWGDQ/Core/MCSignalLibrary.cxx b/PWGDQ/Core/MCSignalLibrary.cxx index 5e4f2ada1bb..4d6bd11a916 100644 --- a/PWGDQ/Core/MCSignalLibrary.cxx +++ b/PWGDQ/Core/MCSignalLibrary.cxx @@ -87,12 +87,33 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) signal = new MCSignal(name, "Primary Kaons", {prong}, {-1}); // define the signal using the full constructor return signal; } + if (!nameStr.compare("proton")) { + MCProng prong(1, {2212}, {true}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "proton", {prong}, {-1}); + return signal; + } if (!nameStr.compare("protonPrimary")) { MCProng prong(1, {2212}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(name, "Primary Proton", {prong}, {-1}); // define the signal using the full constructor return signal; } + if (!nameStr.compare("protonFromTransport")) { + MCProng prong(1, {2212}, {true}, {false}, {0}, {0}, {false}); + prong.SetSourceBit(0, MCProng::kProducedInTransport); + signal = new MCSignal(name, "ProtonFromTransport", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("protonFromLambda0")) { + MCProng prong(2, {2212, 3122}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Proton from Lambda0 decays", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("protonFromSigmaPlus")) { + MCProng prong(2, {2212, 3222}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Proton from Sigma+ decays", {prong}, {-1}); + return signal; + } if (!nameStr.compare("phiMeson")) { MCProng prong(1, {333}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor signal = new MCSignal(name, "phi meson", {prong}, {-1}); // define the signal using the full constructor diff --git a/PWGDQ/Core/MixingLibrary.cxx b/PWGDQ/Core/MixingLibrary.cxx index 0682a224ad3..2f2f755269d 100644 --- a/PWGDQ/Core/MixingLibrary.cxx +++ b/PWGDQ/Core/MixingLibrary.cxx @@ -64,6 +64,18 @@ void o2::aod::dqmixing::SetUpMixing(MixingHandler* mh, const char* mixingVarible std::vector fCentFT0CLimsHashing = {0.0f, 2.5f, 5.0f, 7.5f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing.size(), fCentFT0CLimsHashing); } + if (!nameStr.compare("Mult1")) { + std::vector fMultLimsHashing = {0.0f, 10.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 120.0f, 160.0f, 350.0f}; + mh->AddMixingVariable(VarManager::kVtxNcontrib, fMultLimsHashing.size(), fMultLimsHashing); + } + if (!nameStr.compare("Mult2")) { + std::vector fMultLimsHashing = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 120.0f, 140.0f, 180.0f, 350.0f}; + mh->AddMixingVariable(VarManager::kVtxNcontrib, fMultLimsHashing.size(), fMultLimsHashing); + } + if (!nameStr.compare("Mult3")) { + std::vector fMultLimsHashing = {0.0f, 5.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 35.0f, 40.0f, 45.0f, 50.0f, 55.0f, 60.0f, 65.0f, 70.0f, 75.0f, 80.0f, 85.0f, 90.0f, 100.0f, 120.0f, 140.0f, 165.0f, 200.0f, 350.0f}; + mh->AddMixingVariable(VarManager::kVtxNcontrib, fMultLimsHashing.size(), fMultLimsHashing); + } if (!nameStr.compare("Vtx1")) { std::vector fZLimsHashing = {-10.0f, 0.0f, 10.0f}; mh->AddMixingVariable(VarManager::kVtxZ, fZLimsHashing.size(), fZLimsHashing); diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 4bb8c419ad7..eb263b73373 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -45,6 +45,8 @@ o2::vertexing::FwdDCAFitterN<3> VarManager::fgFitterThreeProngFwd; o2::globaltracking::MatchGlobalFwd VarManager::mMatching; std::map VarManager::fgCalibs; bool VarManager::fgRunTPCPostCalibration[4] = {false, false, false, false}; +int VarManager::fgCalibrationType = 0; // 0 - no calibration, 1 - calibration vs (TPCncls,pIN,eta) typically for pp, 2 - calibration vs (eta,nPV,nLong,tLong) typically for PbPb +bool VarManager::fgUseInterpolatedCalibration = true; // use interpolated calibration histograms (default: true) //__________________________________________________________________ VarManager::VarManager() : TObject() @@ -209,6 +211,148 @@ float VarManager::calculateCosPA(KFParticle kfp, KFParticle PV) { return cpaFromKF(kfp, PV); } + +//__________________________________________________________________ +double VarManager::ComputePIDcalibration(int species, double nSigmaValue) +{ + // species: 0 - electron, 1 - pion, 2 - kaon, 3 - proton + // Depending on the PID calibration type, we use different types of calibration histograms + + if (fgCalibrationType == 1) { + // get the calibration histograms + CalibObjects calibMean, calibSigma; + switch (species) { + case 0: + calibMean = kTPCElectronMean; + calibSigma = kTPCElectronSigma; + break; + case 1: + calibMean = kTPCPionMean; + calibSigma = kTPCPionSigma; + break; + case 2: + calibMean = kTPCKaonMean; + calibSigma = kTPCKaonSigma; + break; + case 3: + calibMean = kTPCProtonMean; + calibSigma = kTPCProtonSigma; + break; + default: + LOG(fatal) << "Invalid species for PID calibration: " << species; + return -999.0; // Return zero if species is invalid + }; + + TH3F* calibMeanHist = reinterpret_cast(fgCalibs[calibMean]); + TH3F* calibSigmaHist = reinterpret_cast(fgCalibs[calibSigma]); + if (!calibMeanHist || !calibSigmaHist) { + LOG(fatal) << "Calibration histograms not found for species: " << species; + return -999.0; // Return zero if histograms are not found + } + + // Get the bin indices for the calibration histograms + int binTPCncls = calibMeanHist->GetXaxis()->FindBin(fgValues[kTPCncls]); + binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls); + binTPCncls = (binTPCncls > calibMeanHist->GetXaxis()->GetNbins() ? calibMeanHist->GetXaxis()->GetNbins() : binTPCncls); + int binPin = calibMeanHist->GetYaxis()->FindBin(fgValues[kPin]); + binPin = (binPin == 0 ? 1 : binPin); + binPin = (binPin > calibMeanHist->GetYaxis()->GetNbins() ? calibMeanHist->GetYaxis()->GetNbins() : binPin); + int binEta = calibMeanHist->GetZaxis()->FindBin(fgValues[kEta]); + binEta = (binEta == 0 ? 1 : binEta); + binEta = (binEta > calibMeanHist->GetZaxis()->GetNbins() ? calibMeanHist->GetZaxis()->GetNbins() : binEta); + + double mean = calibMeanHist->GetBinContent(binTPCncls, binPin, binEta); + double sigma = calibSigmaHist->GetBinContent(binTPCncls, binPin, binEta); + return (nSigmaValue - mean) / sigma; // Return the calibrated nSigma value + } else if (fgCalibrationType == 2) { + // get the calibration histograms + CalibObjects calibMean, calibSigma, calibStatus; + switch (species) { + case 0: + calibMean = kTPCElectronMean; + calibSigma = kTPCElectronSigma; + calibStatus = kTPCElectronStatus; + break; + case 1: + calibMean = kTPCPionMean; + calibSigma = kTPCPionSigma; + calibStatus = kTPCPionStatus; + break; + case 2: + calibMean = kTPCKaonMean; + calibSigma = kTPCKaonSigma; + calibStatus = kTPCKaonStatus; + break; + case 3: + calibMean = kTPCProtonMean; + calibSigma = kTPCProtonSigma; + calibStatus = kTPCProtonStatus; + break; + default: + LOG(fatal) << "Invalid species for PID calibration: " << species; + return -999.0; // Return zero if species is invalid + }; + + THnF* calibMeanHist = reinterpret_cast(fgCalibs[calibMean]); + THnF* calibSigmaHist = reinterpret_cast(fgCalibs[calibSigma]); + THnF* calibStatusHist = reinterpret_cast(fgCalibs[calibStatus]); + if (!calibMeanHist || !calibSigmaHist || !calibStatusHist) { + LOG(fatal) << "Calibration histograms not found for species: " << species; + return -999.0; // Return zero if histograms are not found + } + + // Get the bin indices for the calibration histograms + int binEta = calibMeanHist->GetAxis(0)->FindBin(fgValues[kEta]); + binEta = (binEta == 0 ? 1 : binEta); + binEta = (binEta > calibMeanHist->GetAxis(0)->GetNbins() ? calibMeanHist->GetAxis(0)->GetNbins() : binEta); + int binNpv = calibMeanHist->GetAxis(1)->FindBin(fgValues[kVtxNcontribReal]); + binNpv = (binNpv == 0 ? 1 : binNpv); + binNpv = (binNpv > calibMeanHist->GetAxis(1)->GetNbins() ? calibMeanHist->GetAxis(1)->GetNbins() : binNpv); + int binNlong = calibMeanHist->GetAxis(2)->FindBin(fgValues[kNTPCcontribLongA]); + binNlong = (binNlong == 0 ? 1 : binNlong); + binNlong = (binNlong > calibMeanHist->GetAxis(2)->GetNbins() ? calibMeanHist->GetAxis(2)->GetNbins() : binNlong); + int binTlong = calibMeanHist->GetAxis(3)->FindBin(fgValues[kNTPCmedianTimeLongA]); + binTlong = (binTlong == 0 ? 1 : binTlong); + binTlong = (binTlong > calibMeanHist->GetAxis(3)->GetNbins() ? calibMeanHist->GetAxis(3)->GetNbins() : binTlong); + + int bin[4] = {binEta, binNpv, binNlong, binTlong}; + int status = static_cast(calibStatusHist->GetBinContent(bin)); + double mean = calibMeanHist->GetBinContent(bin); + double sigma = calibSigmaHist->GetBinContent(bin); + switch (status) { + case 0: + // good calibration, return the calibrated nSigma value + return (nSigmaValue - mean) / sigma; + break; + case 1: + // calibration not valid, return the original nSigma value + return nSigmaValue; + break; + case 2: // calibration constant has poor stat uncertainty, consider the user option for what to do + case 3: + // calibration constants have been interpolated + if (fgUseInterpolatedCalibration) { + return (nSigmaValue - mean) / sigma; + } else { + // return the original nSigma value + return nSigmaValue; + } + break; + case 4: + // calibration constants interpolation failed, return the original nSigma value + return nSigmaValue; + break; + default: + return nSigmaValue; // unknown status, return the original nSigma value + break; + }; + } else { + // unknown calibration type, return the original nSigma value + LOG(fatal) << "Unknown calibration type: " << fgCalibrationType; + return nSigmaValue; // Return the original nSigma value + } +} + //__________________________________________________________________ void VarManager::SetDefaultVarNames() { @@ -1451,8 +1595,6 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kTPCnCRoverFindCls"] = kTPCnCRoverFindCls; fgVarNamesMap["kTPCchi2"] = kTPCchi2; fgVarNamesMap["kTPCsignal"] = kTPCsignal; - fgVarNamesMap["kTPCsignalRandomized"] = kTPCsignalRandomized; - fgVarNamesMap["kTPCsignalRandomizedDelta"] = kTPCsignalRandomizedDelta; fgVarNamesMap["kPhiTPCOuter"] = kPhiTPCOuter; fgVarNamesMap["kTrackIsInsideTPCModule"] = kTrackIsInsideTPCModule; fgVarNamesMap["kTRDsignal"] = kTRDsignal; @@ -1476,20 +1618,14 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kTrackCTglTgl"] = kTrackCTglTgl; fgVarNamesMap["kTrackC1Pt21Pt2"] = kTrackC1Pt21Pt2; fgVarNamesMap["kTPCnSigmaEl"] = kTPCnSigmaEl; - fgVarNamesMap["kTPCnSigmaElRandomized"] = kTPCnSigmaElRandomized; - fgVarNamesMap["kTPCnSigmaElRandomizedDelta"] = kTPCnSigmaElRandomizedDelta; fgVarNamesMap["kTPCnSigmaMu"] = kTPCnSigmaMu; fgVarNamesMap["kTPCnSigmaPi"] = kTPCnSigmaPi; - fgVarNamesMap["kTPCnSigmaPiRandomized"] = kTPCnSigmaPiRandomized; - fgVarNamesMap["kTPCnSigmaPiRandomizedDelta"] = kTPCnSigmaPiRandomizedDelta; fgVarNamesMap["kTPCnSigmaKa"] = kTPCnSigmaKa; fgVarNamesMap["kTPCnSigmaPr"] = kTPCnSigmaPr; fgVarNamesMap["kTPCnSigmaEl_Corr"] = kTPCnSigmaEl_Corr; fgVarNamesMap["kTPCnSigmaPi_Corr"] = kTPCnSigmaPi_Corr; fgVarNamesMap["kTPCnSigmaKa_Corr"] = kTPCnSigmaKa_Corr; fgVarNamesMap["kTPCnSigmaPr_Corr"] = kTPCnSigmaPr_Corr; - fgVarNamesMap["kTPCnSigmaPrRandomized"] = kTPCnSigmaPrRandomized; - fgVarNamesMap["kTPCnSigmaPrRandomizedDelta"] = kTPCnSigmaPrRandomizedDelta; fgVarNamesMap["kTOFnSigmaEl"] = kTOFnSigmaEl; fgVarNamesMap["kTOFnSigmaMu"] = kTOFnSigmaMu; fgVarNamesMap["kTOFnSigmaPi"] = kTOFnSigmaPi; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index d49e71677da..130634f60b9 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -50,6 +50,7 @@ #include "Math/VectorUtil.h" #include "TGeoGlobalMagField.h" #include "TH3F.h" +#include "THn.h" #include "TRandom.h" #include #include @@ -506,8 +507,6 @@ class VarManager : public TObject kTPCnCRoverFindCls, kTPCchi2, kTPCsignal, - kTPCsignalRandomized, - kTPCsignalRandomizedDelta, kPhiTPCOuter, kTrackIsInsideTPCModule, kTRDsignal, @@ -531,20 +530,14 @@ class VarManager : public TObject kTrackCTglTgl, kTrackC1Pt21Pt2, kTPCnSigmaEl, - kTPCnSigmaElRandomized, - kTPCnSigmaElRandomizedDelta, kTPCnSigmaMu, kTPCnSigmaPi, - kTPCnSigmaPiRandomized, - kTPCnSigmaPiRandomizedDelta, kTPCnSigmaKa, kTPCnSigmaPr, kTPCnSigmaEl_Corr, kTPCnSigmaPi_Corr, kTPCnSigmaKa_Corr, kTPCnSigmaPr_Corr, - kTPCnSigmaPrRandomized, - kTPCnSigmaPrRandomizedDelta, kTOFnSigmaEl, kTOFnSigmaMu, kTOFnSigmaPi, @@ -866,12 +859,16 @@ class VarManager : public TObject enum CalibObjects { kTPCElectronMean = 0, kTPCElectronSigma, + kTPCElectronStatus, kTPCPionMean, kTPCPionSigma, + kTPCPionStatus, kTPCKaonMean, kTPCKaonSigma, + kTPCKaonStatus, kTPCProtonMean, kTPCProtonSigma, + kTPCProtonStatus, kNCalibObjects }; @@ -1156,6 +1153,17 @@ class VarManager : public TObject fgUsedVars[kTPCnSigmaPr_Corr] = true; } } + + static void SetCalibrationType(int type, bool useInterpolation = true) + { + if (type < 0 || type > 2) { + LOG(fatal) << "Invalid calibration type. Must be 0, 1, or 2."; + } + fgCalibrationType = type; + fgUseInterpolatedCalibration = useInterpolation; + } + static double ComputePIDcalibration(int species, double nSigmaValue); + static TObject* GetCalibrationObject(CalibObjects calib) { auto obj = fgCalibs.find(calib); @@ -1231,11 +1239,13 @@ class VarManager : public TObject static std::map fgCalibs; // map of calibration histograms static bool fgRunTPCPostCalibration[4]; // 0-electron, 1-pion, 2-kaon, 3-proton + static int fgCalibrationType; // 0 - no calibration, 1 - calibration vs (TPCncls,pIN,eta) typically for pp, 2 - calibration vs (eta,nPV,nLong,tLong) typically for PbPb + static bool fgUseInterpolatedCalibration; // use interpolated calibration histograms (default: true) VarManager& operator=(const VarManager& c); VarManager(const VarManager& c); - ClassDef(VarManager, 3); + ClassDef(VarManager, 4); }; template @@ -2434,92 +2444,38 @@ void VarManager::FillTrack(T const& track, float* values) } // compute TPC postcalibrated electron nsigma based on calibration histograms from CCDB if (fgUsedVars[kTPCnSigmaEl_Corr] && fgRunTPCPostCalibration[0]) { - TH3F* calibMean = reinterpret_cast(fgCalibs[kTPCElectronMean]); - TH3F* calibSigma = reinterpret_cast(fgCalibs[kTPCElectronSigma]); - - int binTPCncls = calibMean->GetXaxis()->FindBin(values[kTPCncls]); - binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls); - binTPCncls = (binTPCncls > calibMean->GetXaxis()->GetNbins() ? calibMean->GetXaxis()->GetNbins() : binTPCncls); - int binPin = calibMean->GetYaxis()->FindBin(values[kPin]); - binPin = (binPin == 0 ? 1 : binPin); - binPin = (binPin > calibMean->GetYaxis()->GetNbins() ? calibMean->GetYaxis()->GetNbins() : binPin); - int binEta = calibMean->GetZaxis()->FindBin(values[kEta]); - binEta = (binEta == 0 ? 1 : binEta); - binEta = (binEta > calibMean->GetZaxis()->GetNbins() ? calibMean->GetZaxis()->GetNbins() : binEta); - - double mean = calibMean->GetBinContent(binTPCncls, binPin, binEta); - double width = calibSigma->GetBinContent(binTPCncls, binPin, binEta); if (!isTPCCalibrated) { - values[kTPCnSigmaEl_Corr] = (values[kTPCnSigmaEl] - mean) / width; + values[kTPCnSigmaEl_Corr] = ComputePIDcalibration(0, values[kTPCnSigmaEl]); } else { + LOG(fatal) << "TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration."; values[kTPCnSigmaEl_Corr] = track.tpcNSigmaEl(); } } + // compute TPC postcalibrated pion nsigma if required if (fgUsedVars[kTPCnSigmaPi_Corr] && fgRunTPCPostCalibration[1]) { - TH3F* calibMean = reinterpret_cast(fgCalibs[kTPCPionMean]); - TH3F* calibSigma = reinterpret_cast(fgCalibs[kTPCPionSigma]); - - int binTPCncls = calibMean->GetXaxis()->FindBin(values[kTPCncls]); - binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls); - binTPCncls = (binTPCncls > calibMean->GetXaxis()->GetNbins() ? calibMean->GetXaxis()->GetNbins() : binTPCncls); - int binPin = calibMean->GetYaxis()->FindBin(values[kPin]); - binPin = (binPin == 0 ? 1 : binPin); - binPin = (binPin > calibMean->GetYaxis()->GetNbins() ? calibMean->GetYaxis()->GetNbins() : binPin); - int binEta = calibMean->GetZaxis()->FindBin(values[kEta]); - binEta = (binEta == 0 ? 1 : binEta); - binEta = (binEta > calibMean->GetZaxis()->GetNbins() ? calibMean->GetZaxis()->GetNbins() : binEta); - - double mean = calibMean->GetBinContent(binTPCncls, binPin, binEta); - double width = calibSigma->GetBinContent(binTPCncls, binPin, binEta); if (!isTPCCalibrated) { - values[kTPCnSigmaPi_Corr] = (values[kTPCnSigmaPi] - mean) / width; + values[kTPCnSigmaPi_Corr] = ComputePIDcalibration(1, values[kTPCnSigmaPi]); } else { + LOG(fatal) << "TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration."; values[kTPCnSigmaPi_Corr] = track.tpcNSigmaPi(); } } if (fgUsedVars[kTPCnSigmaKa_Corr] && fgRunTPCPostCalibration[2]) { - TH3F* calibMean = reinterpret_cast(fgCalibs[kTPCKaonMean]); - TH3F* calibSigma = reinterpret_cast(fgCalibs[kTPCKaonSigma]); - - int binTPCncls = calibMean->GetXaxis()->FindBin(values[kTPCncls]); - binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls); - binTPCncls = (binTPCncls > calibMean->GetXaxis()->GetNbins() ? calibMean->GetXaxis()->GetNbins() : binTPCncls); - int binPin = calibMean->GetYaxis()->FindBin(values[kPin]); - binPin = (binPin == 0 ? 1 : binPin); - binPin = (binPin > calibMean->GetYaxis()->GetNbins() ? calibMean->GetYaxis()->GetNbins() : binPin); - int binEta = calibMean->GetZaxis()->FindBin(values[kEta]); - binEta = (binEta == 0 ? 1 : binEta); - binEta = (binEta > calibMean->GetZaxis()->GetNbins() ? calibMean->GetZaxis()->GetNbins() : binEta); - - double mean = calibMean->GetBinContent(binTPCncls, binPin, binEta); - double width = calibSigma->GetBinContent(binTPCncls, binPin, binEta); + // compute TPC postcalibrated kaon nsigma if required if (!isTPCCalibrated) { - values[kTPCnSigmaKa_Corr] = (values[kTPCnSigmaKa] - mean) / width; + values[kTPCnSigmaKa_Corr] = ComputePIDcalibration(2, values[kTPCnSigmaKa]); } else { + LOG(fatal) << "TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration."; values[kTPCnSigmaKa_Corr] = track.tpcNSigmaKa(); } } // compute TPC postcalibrated proton nsigma if required if (fgUsedVars[kTPCnSigmaPr_Corr] && fgRunTPCPostCalibration[3]) { - TH3F* calibMean = reinterpret_cast(fgCalibs[kTPCProtonMean]); - TH3F* calibSigma = reinterpret_cast(fgCalibs[kTPCProtonSigma]); - - int binTPCncls = calibMean->GetXaxis()->FindBin(values[kTPCncls]); - binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls); - binTPCncls = (binTPCncls > calibMean->GetXaxis()->GetNbins() ? calibMean->GetXaxis()->GetNbins() : binTPCncls); - int binPin = calibMean->GetYaxis()->FindBin(values[kPin]); - binPin = (binPin == 0 ? 1 : binPin); - binPin = (binPin > calibMean->GetYaxis()->GetNbins() ? calibMean->GetYaxis()->GetNbins() : binPin); - int binEta = calibMean->GetZaxis()->FindBin(values[kEta]); - binEta = (binEta == 0 ? 1 : binEta); - binEta = (binEta > calibMean->GetZaxis()->GetNbins() ? calibMean->GetZaxis()->GetNbins() : binEta); - - double mean = calibMean->GetBinContent(binTPCncls, binPin, binEta); - double width = calibSigma->GetBinContent(binTPCncls, binPin, binEta); if (!isTPCCalibrated) { - values[kTPCnSigmaPr_Corr] = (values[kTPCnSigmaPr] - mean) / width; + values[kTPCnSigmaPr_Corr] = ComputePIDcalibration(3, values[kTPCnSigmaPr]); } else { + LOG(fatal) << "TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration."; values[kTPCnSigmaPr_Corr] = track.tpcNSigmaPr(); } } @@ -2531,22 +2487,6 @@ void VarManager::FillTrack(T const& track, float* values) values[kTOFnSigmaPr] = track.tofNSigmaPr(); } - if (fgUsedVars[kTPCsignalRandomized] || fgUsedVars[kTPCnSigmaElRandomized] || fgUsedVars[kTPCnSigmaPiRandomized] || fgUsedVars[kTPCnSigmaPrRandomized]) { - // NOTE: this is needed temporarily for the study of the impact of TPC pid degradation on the quarkonium triggers in high lumi pp - // This study involves a degradation from a dE/dx resolution of 5% to one of 6% (20% worsening) - // For this we smear the dE/dx and n-sigmas using a gaus distribution with a width of 3.3% - // which is approx the needed amount to get dE/dx to a resolution of 6% - double randomX = gRandom->Gaus(0.0, 0.033); - values[kTPCsignalRandomized] = values[kTPCsignal] * (1.0 + randomX); - values[kTPCsignalRandomizedDelta] = values[kTPCsignal] * randomX; - values[kTPCnSigmaElRandomized] = values[kTPCnSigmaEl] * (1.0 + randomX); - values[kTPCnSigmaElRandomizedDelta] = values[kTPCnSigmaEl] * randomX; - values[kTPCnSigmaPiRandomized] = values[kTPCnSigmaPi] * (1.0 + randomX); - values[kTPCnSigmaPiRandomizedDelta] = values[kTPCnSigmaPi] * randomX; - values[kTPCnSigmaPrRandomized] = values[kTPCnSigmaPr] * (1.0 + randomX); - values[kTPCnSigmaPrRandomizedDelta] = values[kTPCnSigmaPr] * randomX; - } - if constexpr ((fillMap & ReducedTrackBarrelPID) > 0) { values[kTPCnSigmaMu] = track.tpcNSigmaMu(); values[kTOFnSigmaMu] = track.tofNSigmaMu(); @@ -3262,6 +3202,125 @@ void VarManager::FillPairME(T1 const& t1, T2 const& t2, float* values) values[kDeltaEtaPair2] = v1.Eta() - v2.Eta(); } + // polarization parameters + bool useHE = fgUsedVars[kCosThetaHE] || fgUsedVars[kPhiHE]; // helicity frame + bool useCS = fgUsedVars[kCosThetaCS] || fgUsedVars[kPhiCS]; // Collins-Soper frame + bool usePP = fgUsedVars[kCosThetaPP]; // production plane frame + bool useRM = fgUsedVars[kCosThetaRM]; // Random frame + + if (useHE || useCS || usePP || useRM) { + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; + ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam1_CM{(boostv12(fgBeamA).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam2_CM{(boostv12(fgBeamC).Vect()).Unit()}; + + // using positive sign convention for the first track + ROOT::Math::XYZVectorF v_CM = (t1.sign() > 0 ? v1_CM : v2_CM); + + if (useHE) { + ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; + ROOT::Math::XYZVectorF yaxis_HE{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_HE{(yaxis_HE.Cross(zaxis_HE)).Unit()}; + if (fgUsedVars[kCosThetaHE]) + values[kCosThetaHE] = zaxis_HE.Dot(v_CM); + if (fgUsedVars[kPhiHE]) { + values[kPhiHE] = TMath::ATan2(yaxis_HE.Dot(v_CM), xaxis_HE.Dot(v_CM)); + if (values[kPhiHE] < 0) { + values[kPhiHE] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildeHE]) { + if (fgUsedVars[kCosThetaHE] && fgUsedVars[kPhiHE]) { + if (values[kCosThetaHE] > 0) { + values[kPhiTildeHE] = values[kPhiHE] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildeHE] < 0) { + values[kPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildeHE] = values[kPhiHE] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildeHE] < 0) { + values[kPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildeHE] = -999; // not computable + } + } + } + + if (useCS) { + ROOT::Math::XYZVectorF zaxis_CS{(Beam1_CM - Beam2_CM).Unit()}; + ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; + if (fgUsedVars[kCosThetaCS]) + values[kCosThetaCS] = zaxis_CS.Dot(v_CM); + if (fgUsedVars[kPhiCS]) { + values[kPhiCS] = TMath::ATan2(yaxis_CS.Dot(v_CM), xaxis_CS.Dot(v_CM)); + if (values[kPhiCS] < 0) { + values[kPhiCS] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildeCS]) { + if (fgUsedVars[kCosThetaCS] && fgUsedVars[kPhiCS]) { + if (values[kCosThetaCS] > 0) { + values[kPhiTildeCS] = values[kPhiCS] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildeCS] < 0) { + values[kPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildeCS] = values[kPhiCS] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildeCS] < 0) { + values[kPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildeCS] = -999; // not computable + } + } + } + + if (usePP) { + ROOT::Math::XYZVector zaxis_PP = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); + ROOT::Math::XYZVector yaxis_PP{(v12.Vect()).Unit()}; + ROOT::Math::XYZVector xaxis_PP{(yaxis_PP.Cross(zaxis_PP)).Unit()}; + if (fgUsedVars[kCosThetaPP]) { + values[kCosThetaPP] = zaxis_PP.Dot(v_CM) / std::sqrt(zaxis_PP.Mag2()); + } + if (fgUsedVars[kPhiPP]) { + values[kPhiPP] = TMath::ATan2(yaxis_PP.Dot(v_CM), xaxis_PP.Dot(v_CM)); + if (values[kPhiPP] < 0) { + values[kPhiPP] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildePP]) { + if (fgUsedVars[kCosThetaPP] && fgUsedVars[kPhiPP]) { + if (values[kCosThetaPP] > 0) { + values[kPhiTildePP] = values[kPhiPP] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildePP] < 0) { + values[kPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildePP] = values[kPhiPP] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildePP] < 0) { + values[kPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildePP] = -999; // not computable + } + } + } + + if (useRM) { + double randomCostheta = gRandom->Uniform(-1., 1.); + double randomPhi = gRandom->Uniform(0., 2. * TMath::Pi()); + ROOT::Math::XYZVectorF zaxis_RM(randomCostheta, std::sqrt(1 - randomCostheta * randomCostheta) * std::cos(randomPhi), std::sqrt(1 - randomCostheta * randomCostheta) * std::sin(randomPhi)); + if (fgUsedVars[kCosThetaRM]) + values[kCosThetaRM] = zaxis_RM.Dot(v_CM); + } + } + if constexpr ((fillMap & ReducedEventQvector) > 0 || (fillMap & CollisionQvect) > 0) { // TODO: provide different computations for vn // Compute the scalar product UQ for two muon from different event using Q-vector from A, for second and third harmonic diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index ae5fd853bf9..244a1f7417c 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -752,7 +752,7 @@ DECLARE_SOA_COLUMN(CosThetaRM, costhetaRM, float); //! Cosine in the DECLARE_SOA_COLUMN(CosThetaStarTPC, costhetaStarTPC, float); //! global polarization, event plane reconstructed from TPC tracks DECLARE_SOA_COLUMN(CosThetaStarFT0A, costhetaStarFT0A, float); //! global polarization, event plane reconstructed from FT0A tracks DECLARE_SOA_COLUMN(CosThetaStarFT0C, costhetaStarFT0C, float); //! global polarization, event plane reconstructed from FT0C tracks -DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! [](float pt, float phi) -> float { return pt * std::cos(phi); }); DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! [](float pt, float phi) -> float { return pt * std::sin(phi); }); @@ -832,7 +832,10 @@ DECLARE_SOA_TABLE(DielectronsAll, "AOD", "RTDIELECTRONALL", //! dilepton_track_index::DeviationTrk0KF, dilepton_track_index::DeviationTrk1KF, dilepton_track_index::DeviationxyTrk0KF, dilepton_track_index::DeviationxyTrk1KF, reducedpair::MassKFGeo, reducedpair::Chi2OverNDFKFGeo, reducedpair::DecayLengthKFGeo, reducedpair::DecayLengthOverErrKFGeo, reducedpair::DecayLengthXYKFGeo, reducedpair::DecayLengthXYOverErrKFGeo, reducedpair::PseudoproperDecayTimeKFGeo, reducedpair::PseudoproperDecayTimeErrKFGeo, reducedpair::CosPAKFGeo, reducedpair::PairDCAxyz, reducedpair::PairDCAxy, reducedpair::DeviationPairKF, reducedpair::DeviationxyPairKF, - reducedpair::MassKFGeoTop, reducedpair::Chi2OverNDFKFGeoTop); + reducedpair::MassKFGeoTop, reducedpair::Chi2OverNDFKFGeoTop, + reducedpair::Tauz, reducedpair::Tauxy, + reducedpair::Lz, + reducedpair::Lxy); DECLARE_SOA_TABLE(DimuonsAll, "AOD", "RTDIMUONALL", //! collision::PosX, collision::PosY, collision::PosZ, collision::NumContrib, diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index 60670abfac6..c72742c3225 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -240,6 +240,8 @@ struct TableMaker { // TPC postcalibration related options struct : ConfigurableGroup { Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas(electrons, pions, protons)"}; + Configurable fConfigTPCpostCalibType{"cfgTPCpostCalibType", 1, "1: (TPCncls,pIN,eta) calibration typically for pp, 2: (eta,nPV,nLong,tLong) calibration typically for PbPb"}; + Configurable fConfigTPCuseInterpolatedCalib{"cfgTPCpostCalibUseInterpolation", true, "If true, use interpolated calibration values (default: true)"}; Configurable fConfigComputeTPCpostCalibKaon{"cfgTPCpostCalibKaon", false, "If true, compute TPC post-calibrated n-sigmas for kaons"}; Configurable fConfigIsOnlyforMaps{"cfgIsforMaps", false, "If true, run for postcalibration maps only"}; Configurable fConfigSaveElectronSample{"cfgSaveElectronSample", false, "If true, only save electron sample"}; @@ -1013,6 +1015,7 @@ struct TableMaker { (reinterpret_cast(fStatsList->At(kStatsTracks)))->Fill(fTrackCuts.size() + static_cast(iv0)); } } + // TODO: this part should be removed since the calibration histogram can be filled as any other histogram if (fConfigPostCalibTPC.fConfigIsOnlyforMaps) { if (trackFilteringTag & (static_cast(1) << VarManager::kIsConversionLeg)) { // for electron fHistMan->FillHistClass("TrackBarrel_PostCalibElectron", VarManager::fgValues); @@ -1305,6 +1308,15 @@ struct TableMaker { VarManager::SetCalibrationObject(VarManager::kTPCKaonMean, calibList->FindObject("mean_map_kaon")); VarManager::SetCalibrationObject(VarManager::kTPCKaonSigma, calibList->FindObject("sigma_map_kaon")); } + if (fConfigPostCalibTPC.fConfigTPCpostCalibType == 2) { + VarManager::SetCalibrationObject(VarManager::kTPCElectronStatus, calibList->FindObject("status_map_electron")); + VarManager::SetCalibrationObject(VarManager::kTPCPionStatus, calibList->FindObject("status_map_pion")); + VarManager::SetCalibrationObject(VarManager::kTPCProtonStatus, calibList->FindObject("status_map_proton")); + if (fConfigPostCalibTPC.fConfigComputeTPCpostCalibKaon) { + VarManager::SetCalibrationObject(VarManager::kTPCKaonStatus, calibList->FindObject("status_map_kaon")); + } + } + VarManager::SetCalibrationType(fConfigPostCalibTPC.fConfigTPCpostCalibType, fConfigPostCalibTPC.fConfigTPCuseInterpolatedCalib); } if (fIsRun2 == true) { fGrpMagRun2 = fCCDB->getForTimeStamp(fConfigCCDB.fConfigGrpMagPathRun2, bcs.begin().timestamp()); diff --git a/PWGDQ/Tasks/dqEfficiency.cxx b/PWGDQ/Tasks/dqEfficiency.cxx index bcbaa4fe1bf..3f97216f52d 100644 --- a/PWGDQ/Tasks/dqEfficiency.cxx +++ b/PWGDQ/Tasks/dqEfficiency.cxx @@ -830,7 +830,9 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], - VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop]); + VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], + VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], + VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); } } } diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 95243956b78..b3ef5cf769a 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -1813,7 +1813,9 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], - VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop]); + VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], + VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], + VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); } } } @@ -3270,6 +3272,10 @@ struct AnalysisDileptonTrack { Configurable fConfigUseRemoteField{"cfgUseRemoteField", false, "Chose whether to fetch the magnetic field from ccdb or set it manually"}; Configurable fConfigGRPmagPath{"cfgGrpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable fConfigMCRecSignals{"cfgMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; Configurable fConfigMCGenSignals{"cfgMCGenSignals", "", "Comma separated list of MC signals (generated)"}; @@ -3333,6 +3339,15 @@ struct AnalysisDileptonTrack { } fCurrentRun = 0; + + fCCDB->setURL(fConfigCcdbUrl.value); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + fCCDB->setCreatedNotAfter(fConfigNoLaterThan.value); + if (!o2::base::GeometryManager::isGeometryLoaded()) { + fCCDB->get(fConfigGeoPath); + } + fValuesDilepton = new float[VarManager::kNVars]; fValuesHadron = new float[VarManager::kNVars]; fTrackCutBitMap = 0; @@ -3773,6 +3788,9 @@ struct AnalysisDileptonTrack { VarManager::FillDileptonHadron(dilepton, track, fValuesHadron); VarManager::FillDileptonTrackVertexing(event, lepton1, lepton2, track, fValuesHadron); + if (!track.has_reducedMCTrack()) { + continue; + } auto trackMC = track.reducedMCTrack(); mcDecision = 0; isig = 0; diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 102eb26100f..2b35db2611c 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -1501,7 +1501,7 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], - VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop]); + VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); } } if constexpr (TPairType == pairTypeMuMu) { diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index ae6c450ac3e..6cb6e8b3221 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -197,6 +197,7 @@ using MyEventsQvector = soa::Join; using MyEventsQvectorCentr = soa::Join; using MyEventsQvectorCentrSelected = soa::Join; +using MyEventsHashSelectedQvectorCentr = soa::Join; using MyBarrelTracks = soa::Join; using MyBarrelTracksWithAmbiguities = soa::Join; @@ -563,6 +564,8 @@ struct AnalysisTrackSelection { Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; + Configurable fConfigTPCpostCalibType{"cfgTPCpostCalibType", 1, "1: (TPCncls,pIN,eta) calibration typically for pp, 2: (eta,nPV,nLong,tLong) calibration typically for PbPb"}; + Configurable fConfigTPCuseInterpolatedCalib{"cfgTPCpostCalibUseInterpolation", true, "If true, use interpolated calibration values (default: true)"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; // Track related options Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; @@ -648,6 +651,12 @@ struct AnalysisTrackSelection { VarManager::SetCalibrationObject(VarManager::kTPCPionSigma, calibList->FindObject("sigma_map_pion")); VarManager::SetCalibrationObject(VarManager::kTPCProtonMean, calibList->FindObject("mean_map_proton")); VarManager::SetCalibrationObject(VarManager::kTPCProtonSigma, calibList->FindObject("sigma_map_proton")); + if (fConfigTPCpostCalibType == 2) { + VarManager::SetCalibrationObject(VarManager::kTPCElectronStatus, calibList->FindObject("status_map_electron")); + VarManager::SetCalibrationObject(VarManager::kTPCPionStatus, calibList->FindObject("status_map_pion")); + VarManager::SetCalibrationObject(VarManager::kTPCProtonStatus, calibList->FindObject("status_map_proton")); + } + VarManager::SetCalibrationType(fConfigTPCpostCalibType, fConfigTPCuseInterpolatedCalib); } o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); @@ -1299,7 +1308,7 @@ struct AnalysisSameEventPairing { { LOG(info) << "Starting initialization of AnalysisSameEventPairing (idstoreh)"; fEnableBarrelHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processBarrelOnlySkimmed") || context.mOptions.get("processBarrelOnlyWithCollSkimmed") || context.mOptions.get("processBarrelOnlySkimmedNoCov") || context.mOptions.get("processBarrelOnlySkimmedNoCovWithMultExtra") || context.mOptions.get("processBarrelOnlyWithQvectorCentrSkimmedNoCov"); - fEnableBarrelMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingBarrelSkimmed") || context.mOptions.get("processMixingBarrelSkimmedFlow"); + fEnableBarrelMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingBarrelSkimmed") || context.mOptions.get("processMixingBarrelSkimmedFlow") || context.mOptions.get("processMixingBarrelWithQvectorCentrSkimmedNoCov"); fEnableMuonHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processMuonOnlySkimmed") || context.mOptions.get("processMuonOnlySkimmedMultExtra") || context.mOptions.get("processMixingMuonSkimmed"); fEnableMuonMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingMuonSkimmed"); @@ -1818,7 +1827,8 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], - VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop]); + VarManager::fgValues[VarManager::kKFMassGeoTop], + VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); } } } @@ -2060,6 +2070,9 @@ struct AnalysisSameEventPairing { if constexpr ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0) { VarManager::FillPairVn(t1, t2); } + if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0) { + VarManager::FillPairVn(t1, t2); + } pairSign = t1.sign() + t2.sign(); ncuts = fNCutsBarrel; } @@ -2298,6 +2311,12 @@ struct AnalysisSameEventPairing { runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); } + void processMixingBarrelWithQvectorCentrSkimmedNoCov(soa::Filtered& events, + soa::Join const& trackAssocs, MyBarrelTracksWithAmbiguities const& tracks) + { + runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); + } + void processMixingMuonSkimmed(soa::Filtered& events, soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { @@ -2321,6 +2340,7 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processMixingAllSkimmed, "Run all types of mixed pairing, with skimmed tracks/muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMixingBarrelSkimmed, "Run barrel type mixing pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMixingBarrelSkimmedFlow, "Run barrel type mixing pairing, with flow, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processMixingBarrelWithQvectorCentrSkimmedNoCov, "Run barrel type mixing pairing, with skimmed tracks and with Qvector from central framework", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMixingMuonSkimmed, "Run muon type mixing pairing, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", false); }; diff --git a/PWGEM/Dilepton/Core/DielectronCut.cxx b/PWGEM/Dilepton/Core/DielectronCut.cxx index 7f86c7babbe..5d943b77651 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.cxx +++ b/PWGEM/Dilepton/Core/DielectronCut.cxx @@ -324,11 +324,6 @@ void DielectronCut::SetTOFNsigmaPrRange(float min, float max) // LOG(info) << "Dielectron Cut, set p range for ITS n sigma Pr: " << mMinP_ITSNsigmaPr << " - " << mMaxP_ITSNsigmaPr; // } -void DielectronCut::SetMaxPinMuonTPConly(float max) -{ - mMaxPinMuonTPConly = max; - LOG(info) << "Dielectron Cut, set max pin for Muon ID with TPC only: " << mMaxPinMuonTPConly; -} void DielectronCut::SetPinRangeForPionRejectionTPC(float min, float max) { mMinPinForPionRejectionTPC = min; diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index 0dc108b05c5..6b4930a0db1 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -65,7 +65,7 @@ class DielectronCut : public TNamed kDCAz, kITSNCls, kITSChi2NDF, - // kITSClusterSize, + kITSClusterSize, kPrefilter, kNCuts }; @@ -162,8 +162,8 @@ class DielectronCut : public TNamed return true; } - template - bool IsSelectedTrack(TTrack const& track, TCollision const& collision = 0) const + template + bool IsSelectedTrack(TTrack const& track) const { if (!track.hasITS()) { return false; @@ -199,9 +199,9 @@ class DielectronCut : public TNamed return false; } - // if (!IsSelectedTrack(track, DielectronCuts::kITSClusterSize)) { - // return false; - // } + if (!IsSelectedTrack(track, DielectronCuts::kITSClusterSize)) { + return false; + } if (mRequireITSibAny) { auto hits_ib = std::count_if(its_ib_any_Requirement.second.begin(), its_ib_any_Requirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); @@ -252,36 +252,24 @@ class DielectronCut : public TNamed } // PID cuts - if constexpr (isML) { - if (!PassPIDML(track, collision)) { - return false; - } - } else { - if (track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF()) { // ITSsa - float meanClusterSizeITS = track.meanClusterSizeITS() * std::cos(std::atan(track.tgl())); - if (meanClusterSizeITS < mMinMeanClusterSizeITS || mMaxMeanClusterSizeITS < meanClusterSizeITS) { - return false; - } - } else { // not ITSsa - if (!PassPID(track)) { - return false; - } - } + if (!PassPID(track)) { + return false; } return true; } - template - bool PassPIDML(TTrack const&, TCollision const&) const + template + bool PassPIDML(TTrack const& track) const { - return false; - /*if (!PassTOFif(track)) { // Allows for pre-selection. But potentially dangerous if analyzers are not aware of it - return false; - }*/ - // std::vector inputFeatures = mPIDMlResponse->getInputFeatures(track, collision); - // float binningFeature = mPIDMlResponse->getBinningFeature(track, collision); - // return mPIDMlResponse->isSelectedMl(inputFeatures, binningFeature); + int pbin = lower_bound(mMLBins.begin(), mMLBins.end(), track.tpcInnerParam()) - mMLBins.begin() - 1; + if (pbin < 0) { + pbin = 0; + } else if (static_cast(mMLBins.size()) - 2 < pbin) { + pbin = static_cast(mMLBins.size()) - 2; + } + // LOGF(info, "track.tpcInnerParam() = %f, pbin = %d, track.probElBDT() = %f, mMLCuts[pbin] = %f", track.tpcInnerParam(), pbin, track.probElBDT(), mMLCuts[pbin]); + return track.probElBDT() > mMLCuts[pbin]; } template @@ -307,7 +295,7 @@ class DielectronCut : public TNamed return PassTOFif(track); case static_cast(PIDSchemes::kPIDML): - return true; // don't use kPIDML here. + return PassPIDML(track); case static_cast(PIDSchemes::kTPChadrejORTOFreq_woTOFif): return PassTPConlyhadrej(track) || PassTOFreq(track); @@ -404,8 +392,8 @@ class DielectronCut : public TNamed bool is_in_phi_range = track.phi() > mMinTrackPhi && track.phi() < mMaxTrackPhi; return mRejectTrackPhi ? !is_in_phi_range : is_in_phi_range; } else { - double minTrackPhiMirror = mMinTrackPhi + TMath::Pi(); - double maxTrackPhiMirror = mMaxTrackPhi + TMath::Pi(); + float minTrackPhiMirror = mMinTrackPhi + M_PI; + float maxTrackPhiMirror = mMaxTrackPhi + M_PI; bool is_in_phi_range = (track.phi() > mMinTrackPhi && track.phi() < mMaxTrackPhi) || (track.phi() > minTrackPhiMirror && track.phi() < maxTrackPhiMirror); return mRejectTrackPhi ? !is_in_phi_range : is_in_phi_range; } @@ -423,7 +411,7 @@ class DielectronCut : public TNamed return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; case DielectronCuts::kRelDiffPin: - return mMinRelDiffPin < (track.tpcInnerParam() - track.p()) / track.p() && (track.tpcInnerParam() - track.p()) / track.p() < mMaxRelDiffPin; + return mMinRelDiffPin < (track.p() - track.tpcInnerParam()) / track.tpcInnerParam() && (track.p() - track.tpcInnerParam()) / track.tpcInnerParam() < mMaxRelDiffPin; case DielectronCuts::kTPCChi2NDF: return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; @@ -443,6 +431,9 @@ class DielectronCut : public TNamed case DielectronCuts::kITSChi2NDF: return mMinChi2PerClusterITS < track.itsChi2NCl() && track.itsChi2NCl() < mMaxChi2PerClusterITS; + case DielectronCuts::kITSClusterSize: + return mMinMeanClusterSizeITS < track.meanClusterSizeITS() * std::cos(std::atan(track.tgl())) && track.meanClusterSizeITS() * std::cos(std::atan(track.tgl())) < mMaxMeanClusterSizeITS; + case DielectronCuts::kPrefilter: return track.pfb() <= 0; @@ -499,7 +490,6 @@ class DielectronCut : public TNamed // void SetPRangeForITSNsigmaKa(float min, float max); // void SetPRangeForITSNsigmaPr(float min, float max); - void SetMaxPinMuonTPConly(float max); void SetPinRangeForPionRejectionTPC(float min, float max); void RequireITSibAny(bool flag); void RequireITSib1st(bool flag); @@ -517,6 +507,18 @@ class DielectronCut : public TNamed mPIDMlResponse = mlResponse; } + void SetMLThresholds(const std::vector bins, const std::vector cuts) + { + if (bins.size() != cuts.size() + 1) { + LOG(fatal) << "cuts.size() + 1 mutst be exactly the same as bins.size(). Check your bins and thresholds."; + } + mMLBins = bins; + mMLCuts = cuts; + // for (int i = 0; i < static_cast(mMLBins.size()) - 1; i++) { + // printf("Dielectron cut: mMLBins[%d] = %3.2f, mMLBins[%d] = %3.2f, mMLCuts[%d] = %3.2f\n", i, mMLBins[i], i + 1, mMLBins[i + 1], i, mMLCuts[i]); + // } + } + // Getters bool IsPhotonConversionSelected() const { return mSelectPC; } @@ -553,7 +555,6 @@ class DielectronCut : public TNamed float mMinRelDiffPin{-1e10f}, mMaxRelDiffPin{1e10f}; // max relative difference between p at TPC inner wall and p at PV int mMinNClustersITS{0}, mMaxNClustersITS{7}; // range in number of ITS clusters float mMinChi2PerClusterITS{-1e10f}, mMaxChi2PerClusterITS{1e10f}; // max its fit chi2 per ITS cluster - float mMaxPinMuonTPConly{0.2f}; // max pin cut for muon ID with TPConly float mMinPinForPionRejectionTPC{0.f}, mMaxPinForPionRejectionTPC{1e10f}; // pin range for pion rejection in TPC bool mRequireITSibAny{true}; bool mRequireITSib1st{false}; @@ -597,6 +598,8 @@ class DielectronCut : public TNamed // float mMinP_ITSNsigmaPr{0.0}, mMaxP_ITSNsigmaPr{0.0}; o2::analysis::MlResponseDielectronSingleTrack* mPIDMlResponse{nullptr}; + std::vector mMLBins{}; // binning for a feature variable. e.g. tpcInnerParam + std::vector mMLCuts{}; // threshold for each bin. mMLCuts.size() must be mMLBins.size()-1. ClassDef(DielectronCut, 1); }; diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index c928d1cc71f..8fd18e97c56 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -101,7 +101,7 @@ struct Dilepton { Configurable spresoPath{"spresoPath", "Users/d/dsekihat/PWGEM/dilepton/Qvector/resolution/LHC23zzh/pass3/test", "Path to SP resolution file"}; Configurable spresoHistName{"spresoHistName", "h1_R2_FT0M_BPos_BNeg", "histogram name of SP resolution file"}; - Configurable cfgAnalysisType{"cfgAnalysisType", static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC), "kQC:0, kUPC:1, kFlowV2:2, kFlowV3:3, kPolarization:4, kVM:5, kHFll:6"}; + Configurable cfgAnalysisType{"cfgAnalysisType", static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC), "kQC:0, kUPC:1, kFlowV2:2, kFlowV3:3, kPolarization:4, kHFll:5"}; Configurable cfgEP2Estimator_for_Mix{"cfgEP2Estimator_for_Mix", 3, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; Configurable cfgQvecEstimator{"cfgQvecEstimator", 0, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; @@ -125,10 +125,13 @@ struct Dilepton { ConfigurableAxis ConfMllBins{"ConfMllBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; ConfigurableAxis ConfPtllBins{"ConfPtllBins", {VARIABLE_WIDTH, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; ConfigurableAxis ConfDCAllBins{"ConfDCAllBins", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCAll bins for output histograms"}; + ConfigurableAxis ConfYllBins{"ConYllBins", {1, -1.f, 1.f}, "yll bins for output histograms"}; // pair rapidity // ConfigurableAxis ConfMmumuBins{"ConfMmumuBins", {VARIABLE_WIDTH, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.10, 5.20, 5.30, 5.40, 5.50, 5.60, 5.70, 5.80, 5.90, 6.00, 6.10, 6.20, 6.30, 6.40, 6.50, 6.60, 6.70, 6.80, 6.90, 7.00, 7.10, 7.20, 7.30, 7.40, 7.50, 7.60, 7.70, 7.80, 7.90, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.50, 12.00}, "mmumu bins for output histograms"}; // for dimuon. one can copy bins here to hyperloop page. ConfigurableAxis ConfSPBins{"ConfSPBins", {200, -5, 5}, "SP bins for flow analysis"}; + ConfigurableAxis ConfPolarizationPhiBins{"ConfPolarizationPhiBins", {6, 0.f, M_PI}, "phi bins for polarization analysis"}; + ConfigurableAxis ConfPolarizationCosThetaBins{"ConfPolarizationCosThetaBins", {5, 0.f, 1.f}, "phi bins for polarization analysis"}; EMEventCut fEMEventCut; struct : ConfigurableGroup { @@ -524,9 +527,11 @@ struct Dilepton { std::string mass_axis_title = "m_{ll} (GeV/c^{2})"; std::string pair_pt_axis_title = "p_{T,ll} (GeV/c)"; std::string pair_dca_axis_title = "DCA_{ll} (#sigma)"; + std::string pair_y_axis_title = "y_{ll}"; if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { mass_axis_title = "m_{ee} (GeV/c^{2})"; pair_pt_axis_title = "p_{T,ee} (GeV/c)"; + pair_y_axis_title = "y_{ee}"; pair_dca_axis_title = "DCA_{ee}^{3D} (#sigma)"; if (cfgDCAType == 1) { pair_dca_axis_title = "DCA_{ee}^{XY} (#sigma)"; @@ -540,15 +545,17 @@ struct Dilepton { mass_axis_title = "m_{#mu#mu} (GeV/c^{2})"; pair_pt_axis_title = "p_{T,#mu#mu} (GeV/c)"; pair_dca_axis_title = "DCA_{#mu#mu}^{XY} (#sigma)"; + pair_y_axis_title = "y_{#mu#mu}"; } // pair info const AxisSpec axis_mass{ConfMllBins, mass_axis_title}; const AxisSpec axis_pt{ConfPtllBins, pair_pt_axis_title}; const AxisSpec axis_dca{ConfDCAllBins, pair_dca_axis_title}; + const AxisSpec axis_y{ConfYllBins, pair_y_axis_title}; if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC)) { - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca}, true); + fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhi", "#Delta#eta-#Delta#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhiPosition", "#Delta#eta-#Delta#varphi^{*} between 2 tracks;#Delta#varphi^{*} (rad.);#Delta#eta;", kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); @@ -564,8 +571,8 @@ struct Dilepton { const AxisSpec axis_aco{10, 0, 1.f, "#alpha = 1 - #frac{|#varphi_{l^{+}} - #varphi_{l^{-}}|}{#pi}"}; const AxisSpec axis_asym_pt{10, 0, 1.f, "A = #frac{|p_{T,l^{+}} - p_{T,l^{-}}|}{|p_{T,l^{+}} + p_{T,l^{-}}|}"}; const AxisSpec axis_dphi_e_ee{18, 0, M_PI, "#Delta#varphi = #varphi_{l} - #varphi_{ll} (rad.)"}; - const AxisSpec axis_cos_theta_cs{10, 0.f, 1.f, "|cos(#theta_{CS})|"}; - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_cos_theta_cs}, true); + const AxisSpec axis_cos_theta_cs{ConfPolarizationCosThetaBins, "|cos(#theta^{CS})|"}; + fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_cos_theta_cs}, true); fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); fRegistry.addClone("Pair/same/", "Pair/mix/"); @@ -578,51 +585,30 @@ struct Dilepton { const AxisSpec axis_sp{ConfSPBins, Form("#vec{u}_{%d,ll} #upoint #vec{Q}_{%d}^{%s}", nmod, nmod, qvec_det_names[cfgQvecEstimator].data())}; - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_sp}, true); + fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_sp}, true); fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); - fRegistry.add("Pair/mix/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca}, true); + fRegistry.add("Pair/mix/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); fRegistry.addClone("Pair/mix/uls/", "Pair/mix/lspp/"); fRegistry.addClone("Pair/mix/uls/", "Pair/mix/lsmm/"); } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kPolarization)) { - const AxisSpec axis_cos_theta_cs{10, 0.f, 1.f, "|cos(#theta_{CS})|"}; - const AxisSpec axis_phi_cs{18, 0.f, M_PI, "|#varphi_{CS}| (rad.)"}; - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_cos_theta_cs, axis_phi_cs}, true); - fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); - fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); - fRegistry.addClone("Pair/same/", "Pair/mix/"); - } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kVM)) { - std::string pair_y_axis_title = "y_{ll}"; - int nbin_y = 20; - float min_y = -1.0; - float max_y = +1.0; - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - pair_y_axis_title = "y_{ee}"; - nbin_y = 20; - min_y = -1.0; - max_y = +1.0; - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - pair_y_axis_title = "y_{#mu#mu}"; - nbin_y = 25; - min_y = -4.5; - max_y = -2.0; - } - const AxisSpec axis_y{nbin_y, min_y, max_y, pair_y_axis_title}; - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); + const AxisSpec axis_cos_theta_cs{ConfPolarizationCosThetaBins, "|cos(#theta^{CS})|"}; + const AxisSpec axis_phi_cs{ConfPolarizationPhiBins, "|#varphi^{CS}| (rad.)"}; + fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_cos_theta_cs, axis_phi_cs}, true); fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); fRegistry.addClone("Pair/same/", "Pair/mix/"); } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kHFll)) { const AxisSpec axis_dphi_ee{36, -M_PI / 2., 3. / 2. * M_PI, "#Delta#varphi = #varphi_{l1} - #varphi_{l2} (rad.)"}; // for kHFll const AxisSpec axis_deta_ee{40, -2., 2., "#Delta#eta = #eta_{l1} - #eta_{l2}"}; - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_dphi_ee, axis_deta_ee}, true); + fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_dphi_ee, axis_deta_ee}, true); fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); fRegistry.addClone("Pair/same/", "Pair/mix/"); } else { // same as kQC to avoid seg. fault - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca}, true); + fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); fRegistry.addClone("Pair/same/", "Pair/mix/"); @@ -713,30 +699,42 @@ struct Dilepton { // fDielectronCut.SetPRangeForITSNsigmaPr(dielectroncuts.cfg_min_p_ITSNsigmaPr, dielectroncuts.cfg_max_p_ITSNsigmaPr); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - 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 = dielectroncuts.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.; - cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; - } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); - } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); + } + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); + } + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // 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 = dielectroncuts.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.; + // cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } @@ -836,11 +834,11 @@ struct Dilepton { if constexpr (ev_id == 0) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -923,7 +921,7 @@ struct Dilepton { float opAng = o2::aod::pwgem::dilepton::utils::pairutil::getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDeltaEtaDeltaPhi"), dphi, deta, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDeltaEtaDeltaPhiPosition"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { @@ -936,7 +934,7 @@ struct Dilepton { } } } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDeltaEtaDeltaPhi"), dphi, deta, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDeltaEtaDeltaPhiPosition"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { @@ -949,7 +947,7 @@ struct Dilepton { } } } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDeltaEtaDeltaPhi"), dphi, deta, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDeltaEtaDeltaPhiPosition"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { @@ -974,11 +972,11 @@ struct Dilepton { o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(t1, t2, leptonM1, leptonM2, beamE1, beamE2, beamP1, beamP2, cos_thetaCS, phiCS); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, aco, asym, std::fabs(dphi_e_ee), std::fabs(cos_thetaCS), weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), aco, asym, std::fabs(dphi_e_ee), std::fabs(cos_thetaCS), weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, aco, asym, std::fabs(dphi_e_ee), std::fabs(cos_thetaCS), weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), aco, asym, std::fabs(dphi_e_ee), std::fabs(cos_thetaCS), weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, aco, asym, std::fabs(dphi_e_ee), std::fabs(cos_thetaCS), weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), aco, asym, std::fabs(dphi_e_ee), std::fabs(cos_thetaCS), weight); } } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kFlowV2) || cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kFlowV3)) { std::array q2ft0m = {collision.q2xft0m(), collision.q2yft0m()}; @@ -1006,19 +1004,19 @@ struct Dilepton { float sp = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v12.Phi())), static_cast(std::sin(nmod * v12.Phi()))}, qvectors[nmod][cfgQvecEstimator]) / getSPresolution(collision.centFT0C(), collision.trackOccupancyInTimeRange()); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, sp, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), sp, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, sp, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), sp, weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, sp, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), sp, weight); } } else if constexpr (ev_id == 1) { if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } } } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kPolarization)) { @@ -1027,20 +1025,11 @@ struct Dilepton { o2::math_utils::bringToPMPi(phiCS); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, std::fabs(cos_thetaCS), std::fabs(phiCS), weight); - } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, std::fabs(cos_thetaCS), std::fabs(phiCS), weight); - } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, std::fabs(cos_thetaCS), std::fabs(phiCS), weight); - } - - } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kVM)) { - if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), std::fabs(cos_thetaCS), std::fabs(phiCS), weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), std::fabs(cos_thetaCS), std::fabs(phiCS), weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), std::fabs(cos_thetaCS), std::fabs(phiCS), weight); } } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kHFll)) { float dphi = v1.Phi() - v2.Phi(); @@ -1048,20 +1037,20 @@ struct Dilepton { float deta = v1.Eta() - v2.Eta(); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, dphi, deta, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), dphi, deta, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, dphi, deta, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), dphi, deta, weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, dphi, deta, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), dphi, deta, weight); } } else { // same as kQC to avoid seg. fault if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } } @@ -1377,16 +1366,16 @@ struct Dilepton { } // end of DF - template - bool isPairOK(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks) + template + bool isPairOK(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -1470,17 +1459,17 @@ struct Dilepton { auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); for (const auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - if (isPairOK(collision, pos, neg, cut, tracks)) { + if (isPairOK(pos, neg, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), neg.globalIndex())); } } for (const auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - if (isPairOK(collision, pos1, pos2, cut, tracks)) { + if (isPairOK(pos1, pos2, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(pos1.globalIndex(), pos2.globalIndex())); } } for (const auto& [neg1, neg2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - if (isPairOK(collision, neg1, neg2, cut, tracks)) { + if (isPairOK(neg1, neg2, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(neg1.globalIndex(), neg2.globalIndex())); } } @@ -1542,8 +1531,8 @@ struct Dilepton { } PROCESS_SWITCH(Dilepton, processAnalysis, "run dilepton analysis", true); - using FilteredMyCollisionsWithSWT = soa::Filtered; - void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, Types const&... args) + // using FilteredMyCollisionsWithSWT = soa::Filtered; + void processTriggerAnalysis(MyCollisionsWithSWT const& collisions, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); diff --git a/PWGEM/Dilepton/Core/DileptonHadronMPC.h b/PWGEM/Dilepton/Core/DileptonHadronMPC.h index 11fedd03212..28df971c52c 100644 --- a/PWGEM/Dilepton/Core/DileptonHadronMPC.h +++ b/PWGEM/Dilepton/Core/DileptonHadronMPC.h @@ -126,7 +126,7 @@ struct DileptonHadronMPC { // ConfigurableAxis ConfMmumuBins{"ConfMmumuBins", {VARIABLE_WIDTH, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.10, 5.20, 5.30, 5.40, 5.50, 5.60, 5.70, 5.80, 5.90, 6.00, 6.10, 6.20, 6.30, 6.40, 6.50, 6.60, 6.70, 6.80, 6.90, 7.00, 7.10, 7.20, 7.30, 7.40, 7.50, 7.60, 7.70, 7.80, 7.90, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.50, 12.00}, "mmumu bins for output histograms"}; // for dimuon. one can copy bins here to hyperloop page. ConfigurableAxis ConfPtHadronBins{"ConfPtHadronBins", {VARIABLE_WIDTH, 0.00, 0.15, 0.2, 0.3, 0.4, 0.50, 1.00, 2.00, 3.00, 4.00, 5.00}, "pT,h bins for output histograms"}; - ConfigurableAxis ConfRapidityBins{"ConfRapidityBins", {20, -1, 1}, "rapidity bins for output histograms"}; + ConfigurableAxis ConfYllBins{"ConfYllBins", {1, -1.f, 1.f}, "yll bins for output histograms"}; // pair rapidity ConfigurableAxis ConfDEtaBins{"ConfDEtaBins", {120, -6, 6}, "deta bins for output histograms"}; Configurable cfgNbinsDPhi{"cfgNbinsDPhi", 36, "nbins in dphi for output histograms"}; Configurable cfgNbinsCosNDPhi{"cfgNbinsCosNDPhi", 200, "nbins in cos(n(dphi)) for output histograms"}; @@ -495,7 +495,7 @@ struct DileptonHadronMPC { const AxisSpec axis_mass{ConfMllBins, mass_axis_title}; const AxisSpec axis_pt{ConfPtllBins, pair_pt_axis_title}; const AxisSpec axis_dca{ConfDCAllBins, pair_dca_axis_title}; - const AxisSpec axis_y{ConfRapidityBins, pair_rapidity_axis_title}; + const AxisSpec axis_y{ConfYllBins, pair_rapidity_axis_title}; // dilepton-hadron info const AxisSpec axis_deta{ConfDEtaBins, deta_axis_title}; @@ -611,30 +611,42 @@ struct DileptonHadronMPC { fDielectronCut.SetPinRangeForPionRejectionTPC(dielectroncuts.cfg_min_pin_pirejTPC, dielectroncuts.cfg_max_pin_pirejTPC); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - 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 = dielectroncuts.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.; - cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // 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 = dielectroncuts.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.; + // cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } @@ -701,11 +713,11 @@ struct DileptonHadronMPC { if constexpr (ev_id == 0) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -831,8 +843,8 @@ struct DileptonHadronMPC { return true; } - template - bool fillDileptonHadron(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks, TRefTrack const& t3) + template + bool fillDileptonHadron(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks, TRefTrack const& t3) { // this function must be called, if dilepton passes the cut. if constexpr (ev_id == 1) { @@ -860,11 +872,11 @@ struct DileptonHadronMPC { if constexpr (ev_id == 0) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -951,8 +963,8 @@ struct DileptonHadronMPC { return true; } - template - bool fillHadronHadron(TCollision const& collision, TRefTrack const& t1, TRefTrack const& t2, TLeptons const& posLeptons, TLeptons const& negLeptons, TLeptonCut const& cut) + template + bool fillHadronHadron(TRefTrack const& t1, TRefTrack const& t2, TLeptons const& posLeptons, TLeptons const& negLeptons, TLeptonCut const& cut) { if constexpr (ev_id == 0) { if (!fEMTrackCut.IsSelected(t1) || !fEMTrackCut.IsSelected(t2)) { // for charged track @@ -963,11 +975,11 @@ struct DileptonHadronMPC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { for (const auto& pos : posLeptons) { // leptons per collision if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(pos, collision)) { + if (!cut.template IsSelectedTrack(pos)) { continue; } } else { // cut based - if (!cut.template IsSelectedTrack(pos)) { + if (!cut.template IsSelectedTrack(pos)) { continue; } } @@ -978,11 +990,11 @@ struct DileptonHadronMPC { for (const auto& neg : negLeptons) { // leptons per collision if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(neg, collision)) { + if (!cut.template IsSelectedTrack(neg)) { continue; } } else { // cut based - if (!cut.template IsSelectedTrack(neg)) { + if (!cut.template IsSelectedTrack(neg)) { continue; } } @@ -1105,7 +1117,7 @@ struct DileptonHadronMPC { if (is_pair_ok) { nuls++; for (const auto& refTrack : refTracks_per_coll) { - fillDileptonHadron<0>(collision, pos, neg, cut, tracks, refTrack); + fillDileptonHadron<0>(pos, neg, cut, tracks, refTrack); } } } @@ -1114,7 +1126,7 @@ struct DileptonHadronMPC { if (is_pair_ok) { nlspp++; for (const auto& refTrack : refTracks_per_coll) { - fillDileptonHadron<0>(collision, pos1, pos2, cut, tracks, refTrack); + fillDileptonHadron<0>(pos1, pos2, cut, tracks, refTrack); } } } @@ -1123,7 +1135,7 @@ struct DileptonHadronMPC { if (is_pair_ok) { nlsmm++; for (const auto& refTrack : refTracks_per_coll) { - fillDileptonHadron<0>(collision, neg1, neg2, cut, tracks, refTrack); + fillDileptonHadron<0>(neg1, neg2, cut, tracks, refTrack); } } } @@ -1144,7 +1156,7 @@ struct DileptonHadronMPC { } } for (const auto& [ref1, ref2] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_coll, refTracks_per_coll))) { - fillHadronHadron<0>(collision, ref1, ref2, posTracks_per_coll, negTracks_per_coll, cut); + fillHadronHadron<0>(ref1, ref2, posTracks_per_coll, negTracks_per_coll, cut); } } @@ -1262,7 +1274,7 @@ struct DileptonHadronMPC { for (const auto& ref1 : selected_refTracks_in_this_event) { // ref-ref mix for (const auto& ref2 : refTracks_from_event_pool) { // LOGF(info, "ref1.pt() = %f, ref2.pt() = %f", ref1.pt(), ref2.pt()); - fillHadronHadron<1>(collision, ref1, ref2, nullptr, nullptr, nullptr); + fillHadronHadron<1>(ref1, ref2, nullptr, nullptr, nullptr); } } } // end of loop over mixed event pool for hadron-hadron @@ -1279,16 +1291,16 @@ struct DileptonHadronMPC { } // end of DF - template - bool isPairOK(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks) + template + bool isPairOK(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -1348,17 +1360,17 @@ struct DileptonHadronMPC { auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); for (const auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - if (isPairOK(collision, pos, neg, cut, tracks)) { + if (isPairOK(pos, neg, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), neg.globalIndex())); } } for (const auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - if (isPairOK(collision, pos1, pos2, cut, tracks)) { + if (isPairOK(pos1, pos2, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(pos1.globalIndex(), pos2.globalIndex())); } } for (const auto& [neg1, neg2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - if (isPairOK(collision, neg1, neg2, cut, tracks)) { + if (isPairOK(neg1, neg2, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(neg1.globalIndex(), neg2.globalIndex())); } } @@ -1419,8 +1431,8 @@ struct DileptonHadronMPC { } PROCESS_SWITCH(DileptonHadronMPC, processAnalysis, "run dilepton analysis", true); - using FilteredMyCollisionsWithSWT = soa::Filtered; - void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, FilteredRefTracks const& refTracks, Types const&... args) + // using FilteredMyCollisionsWithSWT = soa::Filtered; + void processTriggerAnalysis(MyCollisionsWithSWT const& collisions, FilteredRefTracks const& refTracks, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 57beff3f8f1..abd188b5712 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -113,17 +113,19 @@ struct DileptonMC { ConfigurableAxis ConfDCAllNarrowBins{"ConfDCAllNarrowBins", {200, 0.0, 10.0}, "narrow DCAll bins for output histograms"}; ConfigurableAxis ConfTrackDCA{"ConfTrackDCA", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.5, 3, 3.5, 4, 4.5, 5, 6, 7, 8, 9, 10}, "DCA binning for single tacks"}; - ConfigurableAxis ConfYllBins{"ConfYllBins", {VARIABLE_WIDTH, -10.f, +10.f}, "yll bins for output histograms"}; + ConfigurableAxis ConfYllBins{"ConfYllBins", {1, -1.f, +1.f}, "yll bins for output histograms"}; // ConfigurableAxis ConfMmumuBins{"ConfMmumuBins", {VARIABLE_WIDTH, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.10, 5.20, 5.30, 5.40, 5.50, 5.60, 5.70, 5.80, 5.90, 6.00, 6.10, 6.20, 6.30, 6.40, 6.50, 6.60, 6.70, 6.80, 6.90, 7.00, 7.10, 7.20, 7.30, 7.40, 7.50, 7.60, 7.70, 7.80, 7.90, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.50, 12.00}, "mmumu bins for output histograms"}; // for dimuon. one can copy bins here to hyperloop page. - Configurable cfg_nbin_dphi_ee{"cfg_nbin_dphi_ee", 1, "number of bins for dphi_ee"}; // 36 - Configurable cfg_nbin_deta_ee{"cfg_nbin_deta_ee", 1, "number of bins for deta_ee"}; // 40 - Configurable cfg_nbin_cos_theta_cs{"cfg_nbin_cos_theta_cs", 1, "number of bins for cos theta cs"}; // 10 - Configurable cfg_nbin_phi_cs{"cfg_nbin_phi_cs", 1, "number of bins for phi cs"}; // 18 - Configurable cfg_nbin_aco{"cfg_nbin_aco", 1, "number of bins for acoplanarity"}; // 10 - Configurable cfg_nbin_asym_pt{"cfg_nbin_asym_pt", 1, "number of bins for pt asymmetry"}; // 10 - Configurable cfg_nbin_dphi_e_ee{"cfg_nbin_dphi_e_ee", 1, "number of bins for dphi_ee_e"}; // 18 + Configurable cfg_nbin_dphi_ee{"cfg_nbin_dphi_ee", 1, "number of bins for dphi_ee"}; // 36 + Configurable cfg_nbin_deta_ee{"cfg_nbin_deta_ee", 1, "number of bins for deta_ee"}; // 40 + // Configurable cfg_nbin_cos_theta_cs{"cfg_nbin_cos_theta_cs", 1, "number of bins for cos theta cs"}; // 10 + // Configurable cfg_nbin_phi_cs{"cfg_nbin_phi_cs", 1, "number of bins for phi cs"}; // 10 + Configurable cfg_nbin_aco{"cfg_nbin_aco", 1, "number of bins for acoplanarity"}; // 10 + Configurable cfg_nbin_asym_pt{"cfg_nbin_asym_pt", 1, "number of bins for pt asymmetry"}; // 10 + Configurable cfg_nbin_dphi_e_ee{"cfg_nbin_dphi_e_ee", 1, "number of bins for dphi_ee_e"}; // 18 + ConfigurableAxis ConfPolarizationPhiBins{"ConfPolarizationPhiBins", {6, 0.f, M_PI}, "phi bins for polarization analysis"}; + ConfigurableAxis ConfPolarizationCosThetaBins{"ConfPolarizationCosThetaBins", {5, 0.f, 1.f}, "phi bins for polarization analysis"}; EMEventCut fEMEventCut; struct : ConfigurableGroup { @@ -345,7 +347,6 @@ struct DileptonMC { const AxisSpec axis_y{ConfYllBins, pair_y_axis_title}; const AxisSpec axis_dca{ConfDCAllBins, pair_dca_axis_title}; const AxisSpec axis_pt_meson{ConfPtllBins, "p_{T} (GeV/c)"}; // for omega, phi meson pT spectra - const AxisSpec axis_y_meson{ConfYllBins, "y"}; // rapidity of meson const AxisSpec axis_dca_narrow{ConfDCAllNarrowBins, pair_dca_axis_title}; const AxisSpec axis_dpt{ConfDPtBins, "#Delta p_{T,1}^{gen-rec} + #Delta p_{T,2}^{gen-rec} (GeV/c)"}; @@ -354,14 +355,15 @@ struct DileptonMC { const AxisSpec axis_dphi_ee{cfg_nbin_dphi_ee, -M_PI / 2., 3. / 2. * M_PI, "#Delta#varphi = #varphi_{l1} - #varphi_{l2} (rad.)"}; // for kHFll const AxisSpec axis_deta_ee{cfg_nbin_deta_ee, -2., 2., "#Delta#eta = #eta_{l1} - #eta_{l2}"}; // for kHFll - const AxisSpec axis_cos_theta_cs{cfg_nbin_cos_theta_cs, 0.f, 1.f, "|cos(#theta_{CS})|"}; // for kPolarization, kUPC - const AxisSpec axis_phi_cs{cfg_nbin_phi_cs, 0.f, M_PI, "|#varphi_{CS}| (rad.)"}; // for kPolarization + const AxisSpec axis_cos_theta_cs{ConfPolarizationCosThetaBins, "|cos(#theta^{CS})|"}; // for kPolarization, kUPC + const AxisSpec axis_phi_cs{ConfPolarizationPhiBins, "|#varphi^{CS}| (rad.)"}; // for kPolarization const AxisSpec axis_aco{cfg_nbin_aco, 0, 1.f, "#alpha = 1 - #frac{|#varphi_{l^{+}} - #varphi_{l^{-}}|}{#pi}"}; // for kUPC const AxisSpec axis_asym_pt{cfg_nbin_asym_pt, 0, 1.f, "A = #frac{|p_{T,l^{+}} - p_{T,l^{-}}|}{|p_{T,l^{+}} + p_{T,l^{-}}|}"}; // for kUPC const AxisSpec axis_dphi_e_ee{cfg_nbin_dphi_e_ee, 0, M_PI, "#Delta#varphi = #varphi_{l} - #varphi_{ll} (rad.)"}; // for kUPC + const AxisSpec axis_isInAcc{2, -0.5, 1.5, "is in acc"}; // in acc or not (bool) // generated info - fRegistry.add("Generated/sm/PromptPi0/hs", "gen. dilepton signal", kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_cs, axis_phi_cs, axis_aco, axis_asym_pt, axis_dphi_e_ee}, true); + fRegistry.add("Generated/sm/PromptPi0/hs", "generated dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_cs, axis_phi_cs, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_isInAcc}, true); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptPi0/"); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Eta/"); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/EtaPrime/"); @@ -374,10 +376,10 @@ struct DileptonMC { fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptJPsi/"); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/PromptPsi2S/"); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptPsi2S/"); - fRegistry.add("Generated/sm/Omega2ll/hPtY", "pT of #omega meson", kTH2F, {axis_y_meson, axis_pt_meson}, true); - fRegistry.add("Generated/sm/Phi2ll/hPtY", "pT of #phi meson", kTH2F, {axis_y_meson, axis_pt_meson}, true); + fRegistry.add("Generated/sm/Omega2ll/hPtY", "pT of #omega meson", kTH2D, {axis_y, axis_pt_meson}, true); + fRegistry.add("Generated/sm/Phi2ll/hPtY", "pT of #phi meson", kTH2D, {axis_y, axis_pt_meson}, true); - fRegistry.add("Generated/ccbar/c2l_c2l/hadron_hadron/hs", "generated dilepton signal", kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_cs, axis_phi_cs, axis_aco, axis_asym_pt, axis_dphi_e_ee}, true); + fRegistry.add("Generated/ccbar/c2l_c2l/hadron_hadron/hs", "generated dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_cs, axis_phi_cs, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_isInAcc}, true); fRegistry.addClone("Generated/ccbar/c2l_c2l/hadron_hadron/", "Generated/ccbar/c2l_c2l/meson_meson/"); fRegistry.addClone("Generated/ccbar/c2l_c2l/hadron_hadron/", "Generated/ccbar/c2l_c2l/baryon_baryon/"); fRegistry.addClone("Generated/ccbar/c2l_c2l/hadron_hadron/", "Generated/ccbar/c2l_c2l/meson_baryon/"); @@ -692,30 +694,42 @@ struct DileptonMC { // fDielectronCut.SetPRangeForITSNsigmaPr(dielectroncuts.cfg_min_p_ITSNsigmaPr, dielectroncuts.cfg_max_p_ITSNsigmaPr); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - 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 = dielectroncuts.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.; - cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; - } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); - } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); + } + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); + } + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // 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 = dielectroncuts.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.; + // cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } @@ -822,11 +836,11 @@ struct DileptonMC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -1331,10 +1345,6 @@ struct DileptonMC { for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS // LOGF(info, "pdg1 = %d, pdg2 = %d", t1.pdgCode(), t2.pdgCode()); - if (!isInAcceptance(t1) || !isInAcceptance(t2)) { - continue; - } - if (!t1.isPhysicalPrimary() && !t1.producedByGenerator()) { continue; } @@ -1402,16 +1412,16 @@ struct DileptonMC { if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { continue; } - if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { - continue; - } + // if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { continue; } - if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { - continue; - } + // if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } } float aco = 1.f - std::fabs(dphi) / M_PI; @@ -1424,6 +1434,8 @@ struct DileptonMC { o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(t1, t2, leptonM1, leptonM2, beamE1, beamE2, beamP1, beamP2, cos_thetaCS, phiCS); o2::math_utils::bringToPMPi(phiCS); + bool isInAcc = isInAcceptance(t1) && isInAcceptance(t2); + if (mother_id > -1) { auto mcmother = mcparticles.iteratorAt(mother_id); if (mcmother.isPhysicalPrimary() || mcmother.producedByGenerator()) { @@ -1431,45 +1443,45 @@ struct DileptonMC { switch (std::abs(mcmother.pdgCode())) { case 111: if (IsFromCharm(mcmother, mcparticles) < 0 && IsFromBeauty(mcmother, mcparticles) < 0) { // prompt pi0 - fRegistry.fill(HIST("Generated/sm/PromptPi0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/PromptPi0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { // non-prompt pi0 - fRegistry.fill(HIST("Generated/sm/NonPromptPi0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/NonPromptPi0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; case 221: - fRegistry.fill(HIST("Generated/sm/Eta/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/Eta/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); break; case 331: - fRegistry.fill(HIST("Generated/sm/EtaPrime/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/EtaPrime/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); break; case 113: - fRegistry.fill(HIST("Generated/sm/Rho/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/Rho/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); break; case 223: - fRegistry.fill(HIST("Generated/sm/Omega/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/Omega/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (mcmother.daughtersIds().size() == 2) { // omega->ee - fRegistry.fill(HIST("Generated/sm/Omega2ll/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/Omega2ll/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; case 333: - fRegistry.fill(HIST("Generated/sm/Phi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/Phi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (mcmother.daughtersIds().size() == 2) { // phi->ee - fRegistry.fill(HIST("Generated/sm/Phi2ll/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/Phi2ll/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; case 443: { if (IsFromBeauty(mcmother, mcparticles) > 0) { - fRegistry.fill(HIST("Generated/sm/NonPromptJPsi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/NonPromptJPsi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/sm/PromptJPsi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/PromptJPsi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } case 100443: { if (IsFromBeauty(mcmother, mcparticles) > 0) { - fRegistry.fill(HIST("Generated/sm/NonPromptPsi2S/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/NonPromptPsi2S/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/sm/PromptPsi2S/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/sm/PromptPsi2S/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } @@ -1482,105 +1494,105 @@ struct DileptonMC { auto mp2 = mcparticles.iteratorAt(t2.mothersIds()[0]); switch (hfee_type) { case static_cast(EM_HFeeType::kCe_Ce): { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (isCharmMeson(mp1) && isCharmMeson(mp2)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 411) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dplus_Dminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dplus_Dminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (std::abs(mp1.pdgCode()) == 421 && std::abs(mp2.pdgCode()) == 421) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_D0bar/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_D0bar/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (std::abs(mp1.pdgCode()) == 431 && std::abs(mp2.pdgCode()) == 431) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dsplus_Dsminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dsplus_Dsminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 421) || (std::abs(mp2.pdgCode()) == 411 && std::abs(mp1.pdgCode()) == 421)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_D0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_D0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 431) || (std::abs(mp2.pdgCode()) == 411 && std::abs(mp1.pdgCode()) == 431)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Dspm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Dspm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 421 && std::abs(mp2.pdgCode()) == 431) || (std::abs(mp2.pdgCode()) == 421 && std::abs(mp1.pdgCode()) == 431)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Dspm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Dspm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } } else if (isCharmBaryon(mp1) && isCharmBaryon(mp2)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (std::abs(mp1.pdgCode()) == 4122 && std::abs(mp2.pdgCode()) == 4122) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcplus_Lcminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcplus_Lcminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (std::abs(mp1.pdgCode()) == 4232 && std::abs(mp2.pdgCode()) == 4232) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xicplus_Xicminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xicplus_Xicminus/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (std::abs(mp1.pdgCode()) == 4132 && std::abs(mp2.pdgCode()) == 4132) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xic0_Xic0bar/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xic0_Xic0bar/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (std::abs(mp1.pdgCode()) == 4332 && std::abs(mp2.pdgCode()) == 4332) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Omegac0_Omegac0bar/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Omegac0_Omegac0bar/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 4122 && std::abs(mp2.pdgCode()) == 4232) || (std::abs(mp2.pdgCode()) == 4122 && std::abs(mp1.pdgCode()) == 4232)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcpm_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcpm_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 4122 && std::abs(mp2.pdgCode()) == 4132) || (std::abs(mp2.pdgCode()) == 4122 && std::abs(mp1.pdgCode()) == 4132)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcpm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcpm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 4122 && std::abs(mp2.pdgCode()) == 4332) || (std::abs(mp2.pdgCode()) == 4122 && std::abs(mp1.pdgCode()) == 4332)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcpm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Lcpm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 4232 && std::abs(mp2.pdgCode()) == 4132) || (std::abs(mp2.pdgCode()) == 4232 && std::abs(mp1.pdgCode()) == 4132)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xicpm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xicpm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 4232 && std::abs(mp2.pdgCode()) == 4332) || (std::abs(mp2.pdgCode()) == 4232 && std::abs(mp1.pdgCode()) == 4332)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xicpm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xicpm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 4132 && std::abs(mp2.pdgCode()) == 4332) || (std::abs(mp2.pdgCode()) == 4132 && std::abs(mp1.pdgCode()) == 4332)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xic0_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Xic0_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } } else { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if ((std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 4122) || (std::abs(mp2.pdgCode()) == 411 && std::abs(mp1.pdgCode()) == 4122)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Lcpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Lcpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 4232) || (std::abs(mp2.pdgCode()) == 411 && std::abs(mp1.pdgCode()) == 4232)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 4132) || (std::abs(mp2.pdgCode()) == 411 && std::abs(mp1.pdgCode()) == 4132)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 411 && std::abs(mp2.pdgCode()) == 4332) || (std::abs(mp2.pdgCode()) == 411 && std::abs(mp1.pdgCode()) == 4332)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dpm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 421 && std::abs(mp2.pdgCode()) == 4122) || (std::abs(mp2.pdgCode()) == 421 && std::abs(mp1.pdgCode()) == 4122)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Lcpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Lcpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 421 && std::abs(mp2.pdgCode()) == 4232) || (std::abs(mp2.pdgCode()) == 421 && std::abs(mp1.pdgCode()) == 4232)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 421 && std::abs(mp2.pdgCode()) == 4132) || (std::abs(mp2.pdgCode()) == 421 && std::abs(mp1.pdgCode()) == 4132)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 421 && std::abs(mp2.pdgCode()) == 4332) || (std::abs(mp2.pdgCode()) == 421 && std::abs(mp1.pdgCode()) == 4332)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/D0_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 431 && std::abs(mp2.pdgCode()) == 4122) || (std::abs(mp2.pdgCode()) == 431 && std::abs(mp1.pdgCode()) == 4122)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Lcpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Lcpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 431 && std::abs(mp2.pdgCode()) == 4232) || (std::abs(mp2.pdgCode()) == 431 && std::abs(mp1.pdgCode()) == 4232)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Xicpm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 431 && std::abs(mp2.pdgCode()) == 4132) || (std::abs(mp2.pdgCode()) == 431 && std::abs(mp1.pdgCode()) == 4132)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Xic0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((std::abs(mp1.pdgCode()) == 431 && std::abs(mp2.pdgCode()) == 4332) || (std::abs(mp2.pdgCode()) == 431 && std::abs(mp1.pdgCode()) == 4332)) { - fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/ccbar/c2l_c2l/Dspm_Omegac0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } } break; } case static_cast(EM_HFeeType::kBe_Be): { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (isBeautyMeson(mp1) && isBeautyMeson(mp2)) { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (isBeautyBaryon(mp1) && isBeautyBaryon(mp2)) { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } case static_cast(EM_HFeeType::kBCe_BCe): { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2c2l/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2c2l/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if (isCharmMeson(mp1) && isCharmMeson(mp2)) { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if (isCharmBaryon(mp1) && isCharmBaryon(mp2)) { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2l_b2l/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } case static_cast(EM_HFeeType::kBCe_Be_SameB): { // ULS - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if ((isCharmMeson(mp1) && isBeautyMeson(mp2)) || (isCharmMeson(mp2) && isBeautyMeson(mp1))) { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((isCharmBaryon(mp1) && isBeautyBaryon(mp2)) || (isCharmBaryon(mp2) && isBeautyBaryon(mp1))) { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_sameb/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } @@ -1596,10 +1608,6 @@ struct DileptonMC { for (const auto& [t1, t2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LOGF(info, "pdg1 = %d, pdg2 = %d", t1.pdgCode(), t2.pdgCode()); - if (!isInAcceptance(t1) || !isInAcceptance(t2)) { - continue; - } - if (!t1.isPhysicalPrimary() && !t1.producedByGenerator()) { continue; } @@ -1666,27 +1674,27 @@ struct DileptonMC { if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { continue; } - if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { - continue; - } + // if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { continue; } - if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { - continue; - } + // if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } } - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { - continue; - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { - continue; - } - } + // if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + // if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { + // continue; + // } + // } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + // if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { + // continue; + // } + // } float aco = 1.f - std::fabs(dphi) / M_PI; float asym = std::fabs(v1.Pt() - v2.Pt()) / (v1.Pt() + v2.Pt()); @@ -1697,6 +1705,7 @@ struct DileptonMC { float cos_thetaCS = 999, phiCS = 999.f; o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(t1, t2, leptonM1, leptonM2, beamE1, beamE2, beamP1, beamP2, cos_thetaCS, phiCS); o2::math_utils::bringToPMPi(phiCS); + bool isInAcc = isInAcceptance(t1) && isInAcceptance(t2); if (hfee_type > -1) { auto mp1 = mcparticles.iteratorAt(t1.mothersIds()[0]); @@ -1715,13 +1724,13 @@ struct DileptonMC { LOGF(info, "You should not see kBCe_Be_SameB in LS++. Good luck."); break; case static_cast(EM_HFeeType::kBCe_Be_DiffB): { // LS - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if ((isCharmMeson(mp1) && isBeautyMeson(mp2)) || (isCharmMeson(mp2) && isBeautyMeson(mp1))) { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((isCharmBaryon(mp1) && isBeautyBaryon(mp2)) || (isCharmBaryon(mp2) && isBeautyBaryon(mp1))) { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } @@ -1734,10 +1743,6 @@ struct DileptonMC { for (const auto& [t1, t2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LOGF(info, "pdg1 = %d, pdg2 = %d", t1.pdgCode(), t2.pdgCode()); - if (!isInAcceptance(t1) || !isInAcceptance(t2)) { - continue; - } - if (!t1.isPhysicalPrimary() && !t1.producedByGenerator()) { continue; } @@ -1804,27 +1809,27 @@ struct DileptonMC { if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { continue; } - if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { - continue; - } + // if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { continue; } - if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { - continue; - } + // if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } } - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { - continue; - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { - continue; - } - } + // if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + // if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { + // continue; + // } + // } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + // if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { + // continue; + // } + // } float aco = 1.f - std::fabs(dphi) / M_PI; float asym = std::fabs(v1.Pt() - v2.Pt()) / (v1.Pt() + v2.Pt()); @@ -1835,6 +1840,7 @@ struct DileptonMC { float cos_thetaCS = 999, phiCS = 999.f; o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(t1, t2, leptonM1, leptonM2, beamE1, beamE2, beamP1, beamP2, cos_thetaCS, phiCS); o2::math_utils::bringToPMPi(phiCS); + bool isInAcc = isInAcceptance(t1) && isInAcceptance(t2); if (hfee_type > -1) { auto mp1 = mcparticles.iteratorAt(t1.mothersIds()[0]); @@ -1853,13 +1859,13 @@ struct DileptonMC { LOGF(info, "You should not see kBCe_Be_SameB in LS--. Good luck."); break; case static_cast(EM_HFeeType::kBCe_Be_DiffB): { // LS - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/hadron_hadron/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); if ((isCharmMeson(mp1) && isBeautyMeson(mp2)) || (isCharmMeson(mp2) && isBeautyMeson(mp1))) { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_meson/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else if ((isCharmBaryon(mp1) && isBeautyBaryon(mp2)) || (isCharmBaryon(mp2) && isBeautyBaryon(mp1))) { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/baryon_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } else { - fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee)); + fRegistry.fill(HIST("Generated/bbbar/b2c2l_b2l_diffb/meson_baryon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), isInAcc); } break; } @@ -1871,16 +1877,16 @@ struct DileptonMC { } // end of collision loop } - template - bool isPairOK(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks) + template + bool isPairOK(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; } } @@ -1949,7 +1955,7 @@ struct DileptonMC { continue; } - if (isPairOK(collision, pos, neg, cut, tracks)) { + if (isPairOK(pos, neg, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), neg.globalIndex())); } } @@ -1965,7 +1971,7 @@ struct DileptonMC { continue; } - if (isPairOK(collision, pos1, pos2, cut, tracks)) { + if (isPairOK(pos1, pos2, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(pos1.globalIndex(), pos2.globalIndex())); } } @@ -1980,7 +1986,7 @@ struct DileptonMC { if (cfgEventGeneratorType >= 0 && mccollision_from_neg2.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - if (isPairOK(collision, neg1, neg2, cut, tracks)) { + if (isPairOK(neg1, neg2, cut, tracks)) { passed_pairIds.emplace_back(std::make_pair(neg1.globalIndex(), neg2.globalIndex())); } } @@ -2104,7 +2110,7 @@ struct DileptonMC { continue; } - if (!isPairOK(collision, pos, neg, cut, tracks)) { // without acceptance + if (!isPairOK(pos, neg, cut, tracks)) { // without acceptance continue; } @@ -2242,7 +2248,7 @@ struct DileptonMC { continue; } - if (!isPairOK(collision, pos1, pos2, cut, tracks)) { // without acceptance + if (!isPairOK(pos1, pos2, cut, tracks)) { // without acceptance continue; } @@ -2299,7 +2305,7 @@ struct DileptonMC { if (cfgEventGeneratorType >= 0 && mccollision_from_neg2.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - if (!isPairOK(collision, neg1, neg2, cut, tracks)) { // without acceptance + if (!isPairOK(neg1, neg2, cut, tracks)) { // without acceptance continue; } if ((std::abs(mcneg1.pdgCode()) != pdg_lepton || std::abs(mcneg2.pdgCode()) != pdg_lepton) || (mcneg1.emmceventId() != mcneg2.emmceventId())) { @@ -2316,7 +2322,7 @@ struct DileptonMC { continue; } - if (!isPairOK(collision, neg1, neg2, cut, tracks)) { // without acceptance + if (!isPairOK(neg1, neg2, cut, tracks)) { // without acceptance continue; } diff --git a/PWGEM/Dilepton/Core/PhotonHBT.h b/PWGEM/Dilepton/Core/PhotonHBT.h index 180360e44f3..796f0c5da2b 100644 --- a/PWGEM/Dilepton/Core/PhotonHBT.h +++ b/PWGEM/Dilepton/Core/PhotonHBT.h @@ -589,30 +589,42 @@ struct PhotonHBT { // fDielectronCut.SetPRangeForITSNsigmaPr(dielectroncuts.cfg_min_p_ITSNsigmaPr, dielectroncuts.cfg_max_p_ITSNsigmaPr); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - 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 = dielectroncuts.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.; - cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // 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 = dielectroncuts.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.; + // cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } @@ -840,11 +852,11 @@ struct PhotonHBT { continue; } if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut1.template IsSelectedTrack(pos1, collision) || !cut1.template IsSelectedTrack(ele1, collision)) { + if (!cut1.template IsSelectedTrack(pos1) || !cut1.template IsSelectedTrack(ele1)) { continue; } } else { // cut-based - if (!cut1.template IsSelectedTrack(pos1, collision) || !cut1.template IsSelectedTrack(ele1, collision)) { + if (!cut1.template IsSelectedTrack(pos1) || !cut1.template IsSelectedTrack(ele1)) { continue; } } @@ -868,11 +880,11 @@ struct PhotonHBT { continue; } if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut2.template IsSelectedTrack(pos2, collision) || !cut2.template IsSelectedTrack(ele2, collision)) { + if (!cut2.template IsSelectedTrack(pos2) || !cut2.template IsSelectedTrack(ele2)) { continue; } } else { // cut-based - if (!cut2.template IsSelectedTrack(pos2, collision) || !cut2.template IsSelectedTrack(ele2, collision)) { + if (!cut2.template IsSelectedTrack(pos2) || !cut2.template IsSelectedTrack(ele2)) { continue; } } @@ -986,11 +998,11 @@ struct PhotonHBT { continue; } if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut2.template IsSelectedTrack(pos2, collision) || !cut2.template IsSelectedTrack(ele2, collision)) { + if (!cut2.template IsSelectedTrack(pos2) || !cut2.template IsSelectedTrack(ele2)) { continue; } } else { // cut-based - if (!cut2.template IsSelectedTrack(pos2, collision) || !cut2.template IsSelectedTrack(ele2, collision)) { + if (!cut2.template IsSelectedTrack(pos2) || !cut2.template IsSelectedTrack(ele2)) { continue; } } @@ -1354,11 +1366,11 @@ struct PhotonHBT { continue; } if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(pos, collision) || !cut.template IsSelectedTrack(ele, collision)) { + if (!cut.template IsSelectedTrack(pos) || !cut.template IsSelectedTrack(ele)) { continue; } } else { // cut-based - if (!cut.template IsSelectedTrack(pos, collision) || !cut.template IsSelectedTrack(ele, collision)) { + if (!cut.template IsSelectedTrack(pos) || !cut.template IsSelectedTrack(ele)) { continue; } } diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 4f9744ea769..186efbd0e87 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -246,7 +246,7 @@ struct SingleTrackQC { fRegistry.add("Track/positive/hNclsTPC_Pt", "number of TPC clusters;p_{T,e} (GeV/c);TPC N_{cls}", kTH2F, {axis_pt, {161, -0.5, 160.5}}, false); fRegistry.add("Track/positive/hNcrTPC_Pt", "number of TPC crossed rows;p_{T,e} (GeV/c);TPC N_{CR}", kTH2F, {axis_pt, {161, -0.5, 160.5}}, false); fRegistry.add("Track/positive/hChi2TPC", "chi2/number of TPC clusters;TPC #chi^{2}/N_{CR}", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Track/positive/hDeltaPin", "p_{in} vs. p_{pv};p_{pv} (GeV/c);(p_{in} - p_{pv})/p_{pv}", kTH2F, {{1000, 0, 10}, {200, -1, +1}}, false); + fRegistry.add("Track/positive/hDeltaPin", "p_{in} vs. p_{pv};p_{in} (GeV/c);(p_{pv} - p_{in})/p_{in}", kTH2F, {{1000, 0, 10}, {200, -1, +1}}, false); fRegistry.add("Track/positive/hTPCNcr2Nf", "TPC Ncr/Nfindable;TPC N_{CR}/N_{cls}^{findable}", kTH1F, {{200, 0, 2}}, false); fRegistry.add("Track/positive/hTPCNcls2Nf", "TPC Ncls/Nfindable;TPC N_{cls}/N_{cls}^{findable}", kTH1F, {{200, 0, 2}}, false); fRegistry.add("Track/positive/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); @@ -269,6 +269,7 @@ struct SingleTrackQC { // fRegistry.add("Track/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); // fRegistry.add("Track/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/positive/hProbElBDT", "probability to be e from BDT;p_{in} (GeV/c);BDT score;", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); on ITS #times cos(#lambda);", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITSib", "mean cluster size ITS inner barrel;p_{pv} (GeV/c); on ITS #times cos(#lambda);", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITSob", "mean cluster size ITS outer barrel;p_{pv} (GeV/c); on ITS #times cos(#lambda);", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); @@ -417,30 +418,42 @@ struct SingleTrackQC { // fDielectronCut.SetPRangeForITSNsigmaPr(dielectroncuts.cfg_min_p_ITSNsigmaPr, dielectroncuts.cfg_max_p_ITSNsigmaPr); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - 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 = dielectroncuts.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.; - cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; - } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); - } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); + } + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); + } + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // 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 = dielectroncuts.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.; + // cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } @@ -491,7 +504,9 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/positive/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); fRegistry.fill(HIST("Track/positive/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); fRegistry.fill(HIST("Track/positive/hTPCNclsShared"), track.pt(), track.tpcFractionSharedCls()); - fRegistry.fill(HIST("Track/positive/hDeltaPin"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + if (track.hasTPC()) { + fRegistry.fill(HIST("Track/positive/hDeltaPin"), track.tpcInnerParam(), (track.p() - track.tpcInnerParam()) / track.tpcInnerParam()); + } fRegistry.fill(HIST("Track/positive/hChi2TPC"), track.tpcChi2NCl()); fRegistry.fill(HIST("Track/positive/hChi2ITS"), track.itsChi2NCl()); fRegistry.fill(HIST("Track/positive/hITSClusterMap"), track.itsClusterMap()); @@ -499,6 +514,7 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/positive/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("Track/positive/hTOFbeta"), track.p(), track.beta()); + fRegistry.fill(HIST("Track/positive/hProbElBDT"), track.tpcInnerParam(), track.probElBDT()); fRegistry.fill(HIST("Track/positive/hMeanClusterSizeITS"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); fRegistry.fill(HIST("Track/positive/hMeanClusterSizeITSib"), track.p(), track.meanClusterSizeITSib() * std::cos(std::atan(track.tgl()))); fRegistry.fill(HIST("Track/positive/hMeanClusterSizeITSob"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); @@ -531,7 +547,9 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/negative/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); fRegistry.fill(HIST("Track/negative/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); fRegistry.fill(HIST("Track/negative/hTPCNclsShared"), track.pt(), track.tpcFractionSharedCls()); - fRegistry.fill(HIST("Track/negative/hDeltaPin"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + if (track.hasTPC()) { + fRegistry.fill(HIST("Track/negative/hDeltaPin"), track.tpcInnerParam(), (track.p() - track.tpcInnerParam()) / track.tpcInnerParam()); + } fRegistry.fill(HIST("Track/negative/hChi2TPC"), track.tpcChi2NCl()); fRegistry.fill(HIST("Track/negative/hChi2ITS"), track.itsChi2NCl()); fRegistry.fill(HIST("Track/negative/hITSClusterMap"), track.itsClusterMap()); @@ -539,6 +557,7 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/negative/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("Track/negative/hTOFbeta"), track.p(), track.beta()); + fRegistry.fill(HIST("Track/negative/hProbElBDT"), track.tpcInnerParam(), track.probElBDT()); fRegistry.fill(HIST("Track/negative/hMeanClusterSizeITS"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); fRegistry.fill(HIST("Track/negative/hMeanClusterSizeITSib"), track.p(), track.meanClusterSizeITSib() * std::cos(std::atan(track.tgl()))); fRegistry.fill(HIST("Track/negative/hMeanClusterSizeITSob"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); @@ -643,11 +662,11 @@ struct SingleTrackQC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { for (const auto& track : tracks_per_coll) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(track, collision)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } else { // cut-based - if (!cut.template IsSelectedTrack(track)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } @@ -698,11 +717,11 @@ struct SingleTrackQC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { for (const auto& track : tracks_per_coll) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(track, collision)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } else { // cut-based - if (!cut.template IsSelectedTrack(track)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } @@ -787,8 +806,8 @@ struct SingleTrackQC { } PROCESS_SWITCH(SingleTrackQC, processQC, "run single track QC", true); - using FilteredMyCollisionsWithSWT = soa::Filtered; - void processQC_TriggeredData(FilteredMyCollisionsWithSWT const& collisions, Types const&... args) + // using FilteredMyCollisionsWithSWT = soa::Filtered; + void processQC_TriggeredData(MyCollisionsWithSWT const& collisions, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index 95e4bc97507..02eb4035160 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -286,7 +286,7 @@ struct SingleTrackQCMC { fRegistry.add("Track/lf/positive/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/lf/positive/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); fRegistry.add("Track/lf/positive/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Track/lf/positive/hDeltaPin", "p_{in} vs. p_{pv};p_{pv} (GeV/c);(p_{in} - p_{pv})/p_{pv}", kTH2F, {{1000, 0, 10}, {200, -1, +1}}, false); + fRegistry.add("Track/lf/positive/hDeltaPin", "p_{in} vs. p_{pv};p_{in} (GeV/c);(p_{pv} - p_{in})/p_{in}", kTH2F, {{1000, 0, 10}, {200, -1, +1}}, false); fRegistry.add("Track/lf/positive/hChi2TOF", "TOF Chi2;p_{pv} (GeV/c);chi2", kTH2F, {{1000, 0, 10}, {100, 0, 10}}, false); fRegistry.add("Track/lf/positive/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); fRegistry.add("Track/lf/positive/hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{200, 0, 10}, {200, -1.0f, 1.0f}}, true); @@ -487,30 +487,42 @@ struct SingleTrackQCMC { // fDielectronCut.SetPRangeForITSNsigmaPr(dielectroncuts.cfg_min_p_ITSNsigmaPr, dielectroncuts.cfg_max_p_ITSNsigmaPr); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - 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 = dielectroncuts.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.; - cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // 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 = dielectroncuts.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.; + // cutsMlArr[i][1] = dielectroncuts.cutsMl.value[i]; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } @@ -612,7 +624,9 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hChi2TPC"), track.tpcChi2NCl()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hChi2ITS"), track.itsChi2NCl()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hChi2TOF"), track.p(), track.tofChi2()); - fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDeltaPin"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + if (track.hasTPC()) { + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDeltaPin"), track.tpcInnerParam(), (track.p() - track.tpcInnerParam()) / track.tpcInnerParam()); + } fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hITSClusterMap"), track.itsClusterMap()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hPtGen_DeltaPtOverPtGen"), mctrack.pt(), (track.pt() - mctrack.pt()) / mctrack.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hPtGen_DeltaEta"), mctrack.pt(), track.eta() - mctrack.eta()); @@ -660,7 +674,9 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hChi2TPC"), track.tpcChi2NCl()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hChi2ITS"), track.itsChi2NCl()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hChi2TOF"), track.p(), track.tofChi2()); - fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDeltaPin"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + if (track.hasTPC()) { + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDeltaPin"), track.tpcInnerParam(), (track.p() - track.tpcInnerParam()) / track.tpcInnerParam()); + } fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hITSClusterMap"), track.itsClusterMap()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hPtGen_DeltaPtOverPtGen"), mctrack.pt(), (track.pt() - mctrack.pt()) / mctrack.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hPtGen_DeltaEta"), mctrack.pt(), track.eta() - mctrack.eta()); @@ -806,11 +822,11 @@ struct SingleTrackQCMC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(track, collision)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } else { // cut-based - if (!cut.template IsSelectedTrack(track)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } @@ -1001,11 +1017,11 @@ struct SingleTrackQCMC { } if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(track, collision)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } else { // cut-based - if (!cut.template IsSelectedTrack(track)) { + if (!cut.template IsSelectedTrack(track)) { continue; } } diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index f507a5220ba..ae57b4cf69d 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -33,7 +33,7 @@ namespace pwgem::dilepton::swt { enum class swtAliases : int { // software trigger aliases for EM kHighTrackMult = 0, - kHighFt0Mult, + kHighFt0cFv0Mult, kSingleE, kLMeeIMR, kLMeeHMR, @@ -41,13 +41,12 @@ enum class swtAliases : int { // software trigger aliases for EM kSingleMuLow, kSingleMuHigh, kDiMuon, - kHighFt0cFv0Mult, kNaliases }; const std::unordered_map aliasLabels = { {"fHighTrackMult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighTrackMult)}, - {"fHighFt0Mult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighFt0Mult)}, + {"fHighFt0cFv0Mult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighFt0cFv0Mult)}, {"fSingleE", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleE)}, {"fLMeeIMR", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kLMeeIMR)}, {"fLMeeHMR", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kLMeeHMR)}, @@ -55,20 +54,9 @@ const std::unordered_map aliasLabels = { {"fSingleMuLow", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleMuLow)}, {"fSingleMuHigh", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleMuHigh)}, {"fDiMuon", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kDiMuon)}, - {"fHighFt0cFv0Mult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighFt0cFv0Mult)}, }; } // namespace pwgem::dilepton::swt -// namespace embc -// { -// DECLARE_SOA_COLUMN(IsTriggerTVX, isTriggerTVX, bool); //! kIsTriggerTVX -// DECLARE_SOA_COLUMN(IsNoTimeFrameBorder, isNoTimeFrameBorder, bool); //! kIsNoTimeFrameBorder -// DECLARE_SOA_COLUMN(IsNoITSROFrameBorder, isNoITSROFrameBorder, bool); //! kNoITSROFrameBorder -// DECLARE_SOA_COLUMN(IsCollisionFound, isCollisionFound, bool); //! at least 1 collision is found in this BC. -// } // namespace embc -// DECLARE_SOA_TABLE(EMBCs, "AOD", "EMBC", //! bc information for normalization -// o2::soa::Index<>, embc::IsTriggerTVX, embc::IsNoTimeFrameBorder, embc::IsNoITSROFrameBorder, embc::IsCollisionFound); - DECLARE_SOA_TABLE(EMBCs, "AOD", "EMBC", //! bc information for normalization o2::soa::Index<>, evsel::Alias, evsel::Selection, evsel::Rct); using EMBC = EMBCs::iterator; diff --git a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx index b8575494195..fb1bf5da2a0 100644 --- a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx @@ -136,7 +136,7 @@ struct CreateEMEventDilepton { mRunNumber = bc.runNumber(); } - Preslice perBC = aod::collision::bcId; + // Preslice perBC = aod::collision::bcId; // Preslice perCollision_pcm = aod::v0photonkf::collisionId; // PresliceUnsorted perCollision_el = aod::emprimaryelectron::collisionId; // PresliceUnsorted perCollision_mu = aod::emprimarymuon::collisionId; @@ -163,16 +163,18 @@ struct CreateEMEventDilepton { auto bc = collision.template foundBC_as(); initCCDB(bc); - if (!collision.isSelected()) { // minimal cut for MB - continue; + if (collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + if constexpr (eventtype == EMEventType::kEvent) { + event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); + } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { + event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), collision.centFT0C()); + } else { + event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); + } } - if constexpr (eventtype == EMEventType::kEvent) { - event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); - } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { - event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), collision.centFT0C()); - } else { - event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); + if (!collision.isSelected()) { // minimal cut for MB + continue; } if (!collision.isEoI()) { // events with at least 1 lepton for data reduction. diff --git a/PWGEM/Dilepton/TableProducer/eventSelection.cxx b/PWGEM/Dilepton/TableProducer/eventSelection.cxx index d4d33e83cc5..89acb23000c 100644 --- a/PWGEM/Dilepton/TableProducer/eventSelection.cxx +++ b/PWGEM/Dilepton/TableProducer/eventSelection.cxx @@ -61,6 +61,8 @@ struct EMEventSelection { Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. occupancy"}; Configurable cfgRequireNoCollInTimeRangeStandard{"cfgRequireNoCollInTimeRangeStandard", false, "require no collision in time range standard"}; + Configurable cfgRequireTVXinEMC{"cfgRequireTVXinEMC", false, "require kTVXinEMC (only for EMC analyses)"}; + o2::aod::rctsel::RCTFlagsChecker rctChecker; void init(InitContext&) @@ -113,6 +115,10 @@ struct EMEventSelection { return false; } + if (cfgRequireTVXinEMC && !collision.alias_bit(triggerAliases::kTVXinEMC)) { + return false; + } + if constexpr (std::is_same_v, MyCollisions_Cent::iterator>) { const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { diff --git a/PWGEM/Dilepton/TableProducer/skimmerOTS.cxx b/PWGEM/Dilepton/TableProducer/skimmerOTS.cxx index 997f8c4e6a5..ece9aef306d 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerOTS.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerOTS.cxx @@ -108,6 +108,8 @@ struct skimmerOTS { uint16_t trigger_bitmap = 0; registry.fill(HIST("hEventCounter"), 1); // all + zorro.populateHistRegistry(registry, bc.runNumber()); + if (zorro.isSelected(bc.globalBC())) { // triggered event auto swt_bitset = zorro.getLastResult(); // this has to be called after zorro::isSelected, or simply call zorro.fetch // LOGF(info, "swt_bitset.to_string().c_str() = %s", swt_bitset.to_string().c_str()); diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx index bf1e2b61505..68324a6b40a 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx @@ -174,6 +174,7 @@ struct skimmerPrimaryElectron { fRegistry.add("Track/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); fRegistry.add("Track/hMeanClusterSizeITSib", "mean cluster size ITSib;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); fRegistry.add("Track/hMeanClusterSizeITSob", "mean cluster size ITSob;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); + fRegistry.add("Track/hProbElBDT", "probability to be e from BDT;p_{in} (GeV/c);BDT score;", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); } if (usePIDML) { @@ -370,20 +371,62 @@ struct skimmerPrimaryElectron { return true; } - template - bool isElectron(TTrack const& track) + template + bool isElectron(TCollision const& collision, TTrack const& track, float& probaEl) { + probaEl = 1.f; if (includeITSsa && (track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF())) { return true; } if (usePIDML) { - return true; + if (!isElectron_TOFif(track)) { + return false; + } + o2::dataformats::DCA mDcaInfoCov; + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + + std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); + float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); + + // std::vector outputs = {}; + // bool isSelected = mlResponseSingleTrack.isSelectedMl(inputFeatures, binningFeature, outputs); // 0: hadron, 1:electron + // probaEl = outputs[1]; + // outputs.clear(); + // outputs.shrink_to_fit(); + + // std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); + // float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); + + int pbin = lower_bound(binsMl.value.begin(), binsMl.value.end(), binningFeature) - binsMl.value.begin() - 1; + if (pbin < 0) { + pbin = 0; + } else if (static_cast(binsMl.value.size()) - 2 < pbin) { + pbin = static_cast(binsMl.value.size()) - 2; + } + // LOGF(info, "track.tpcInnerParam() = %f (GeV/c), pbin = %d", track.tpcInnerParam(), pbin); + + probaEl = mlResponseSingleTrack.getModelOutput(inputFeatures, pbin)[1]; // 0: hadron, 1:electron + return probaEl > cutsMl.value[pbin]; + // return isSelected; } else { return isElectron_TPChadrej(track) || isElectron_TOFreq(track); } } + template + bool isElectron_TOFif(TTrack const& track) + { + bool is_EL_TPC = minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl; + bool is_EL_TOF = track.hasTOF() ? (std::fabs(track.tofNSigmaEl()) < maxTOFNsigmaEl) : true; // TOFif + return is_EL_TPC && is_EL_TOF; + } + template bool isElectron_TPChadrej(TTrack const& track) { @@ -415,7 +458,7 @@ struct skimmerPrimaryElectron { } template - void fillTrackTable(TCollision const& collision, TTrack const& track) + void fillTrackTable(TCollision const& collision, TTrack const& track, const float probaEl) { if (std::find(stored_trackIds.begin(), stored_trackIds.end(), std::pair{collision.globalIndex(), track.globalIndex()}) == stored_trackIds.end()) { o2::dataformats::DCA mDcaInfoCov; @@ -439,13 +482,6 @@ struct skimmerPrimaryElectron { mcTunedTPCSignal = track.mcTunedTPCSignal(); } - float probaEl = 1.0; - if (usePIDML) { - std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); - float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); - probaEl = mlResponseSingleTrack.isSelectedMl(inputFeatures, binningFeature); - } - emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), pt_recalc, eta_recalc, phi_recalc, dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), @@ -545,13 +581,14 @@ struct skimmerPrimaryElectron { fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), trackParCov.getP(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(trackParCov.getTgl()))); fRegistry.fill(HIST("Track/hMeanClusterSizeITSib"), trackParCov.getP(), static_cast(total_cluster_size_ib) / static_cast(nl_ib) * std::cos(std::atan(trackParCov.getTgl()))); fRegistry.fill(HIST("Track/hMeanClusterSizeITSob"), trackParCov.getP(), static_cast(total_cluster_size_ob) / static_cast(nl_ob) * std::cos(std::atan(trackParCov.getTgl()))); + fRegistry.fill(HIST("Track/hProbElBDT"), track.tpcInnerParam(), probaEl); } } } Preslice trackIndicesPerCollision = aod::track_association::collisionId; std::vector> stored_trackIds; - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; + Filter trackFilter = o2::aod::track::itsChi2NCl < maxchi2its && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; @@ -573,10 +610,15 @@ struct skimmerPrimaryElectron { auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); for (const auto& track : tracks_per_coll) { - if (!checkTrack(collision, track) || !isElectron(track)) { + float probaEl = 1.0; + if (!checkTrack(collision, track)) { + continue; + } + if (!isElectron(collision, track, probaEl)) { continue; } - fillTrackTable(collision, track); + + fillTrackTable(collision, track, probaEl); } } // end of collision loop @@ -602,10 +644,14 @@ struct skimmerPrimaryElectron { for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(track)) { + float probaEl = 1.0; + if (!checkTrack(collision, track)) { + continue; + } + if (!isElectron(collision, track, probaEl)) { continue; } - fillTrackTable(collision, track); + fillTrackTable(collision, track, probaEl); } } // end of collision loop @@ -632,10 +678,14 @@ struct skimmerPrimaryElectron { auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); for (const auto& track : tracks_per_coll) { - if (!checkTrack(collision, track) || !isElectron(track)) { + float probaEl = 1.0; + if (!checkTrack(collision, track)) { + continue; + } + if (!isElectron(collision, track, probaEl)) { continue; } - fillTrackTable(collision, track); + fillTrackTable(collision, track, probaEl); } } // end of collision loop @@ -664,10 +714,14 @@ struct skimmerPrimaryElectron { for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(track)) { + float probaEl = 1.0; + if (!checkTrack(collision, track)) { continue; } - fillTrackTable(collision, track); + if (!isElectron(collision, track, probaEl)) { + continue; + } + fillTrackTable(collision, track, probaEl); } } // end of collision loop @@ -698,10 +752,14 @@ struct skimmerPrimaryElectron { auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); for (const auto& track : tracks_per_coll) { - if (!checkTrack(collision, track) || !isElectron(track)) { + float probaEl = 1.0; + if (!checkTrack(collision, track)) { continue; } - fillTrackTable(collision, track); + if (!isElectron(collision, track, probaEl)) { + continue; + } + fillTrackTable(collision, track, probaEl); } } // end of collision loop @@ -729,10 +787,14 @@ struct skimmerPrimaryElectron { for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(track)) { + float probaEl = 1.0; + if (!checkTrack(collision, track)) { + continue; + } + if (!isElectron(collision, track, probaEl)) { continue; } - fillTrackTable(collision, track); + fillTrackTable(collision, track, probaEl); } } // end of collision loop @@ -778,7 +840,6 @@ struct prefilterPrimaryElectron { Configurable slope{"slope", 0.0185, "slope for m vs. phiv"}; Configurable intercept{"intercept", -0.0280, "intercept for m vs. phiv"}; Configurable includeITSsa{"includeITSsa", false, "Flag to include ITSsa tracks"}; - Configurable maxpt_itssa{"maxpt_itssa", 0.15, "mix pt for ITSsa track"}; Configurable maxMeanITSClusterSize{"maxMeanITSClusterSize", 16, "max x cos(lambda)"}; Configurable> max_mee_vec{"max_mee_vec", std::vector{0.06, 0.08, 0.10}, "vector fo max mee for prefilter in ULS. Please sort this by increasing order."}; // currently, 3 thoresholds are allowed. @@ -937,10 +998,6 @@ struct prefilterPrimaryElectron { return false; } - if ((track.hasITS() && !track.hasTPC() && !track.hasTOF() && !track.hasTRD()) && maxpt_itssa < trackParCov.getPt()) { - return false; - } - if (track.hasITS() && !track.hasTPC() && !track.hasTOF() && !track.hasTRD()) { int total_cluster_size = 0, nl = 0; for (unsigned int layer = 0; layer < 7; layer++) { @@ -1002,7 +1059,7 @@ struct prefilterPrimaryElectron { Preslice trackIndicesPerCollision = aod::track_association::collisionId; - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; + Filter trackFilter = o2::aod::track::itsChi2NCl < maxchi2its && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; Partition negTracks = o2::aod::track::signed1Pt < 0.f; diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx index 68b0fad8593..89fc6cd09c3 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx @@ -187,6 +187,7 @@ struct skimmerPrimaryElectronQC { fRegistry.add("Track/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); fRegistry.add("Track/hMeanClusterSizeITSib", "mean cluster size ITSib;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); fRegistry.add("Track/hMeanClusterSizeITSob", "mean cluster size ITSob;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); + 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, {{180, 0.f, M_PI}, {100, 0, 0.1}}); } @@ -467,7 +468,14 @@ struct skimmerPrimaryElectronQC { if (usePIDML) { std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); - probaEl = mlResponseSingleTrack.isSelectedMl(inputFeatures, binningFeature); + + int pbin = lower_bound(binsMl.value.begin(), binsMl.value.end(), binningFeature) - binsMl.value.begin() - 1; + if (pbin < 0) { + pbin = 0; + } else if (static_cast(binsMl.value.size()) - 2 < pbin) { + pbin = static_cast(binsMl.value.size()) - 2; + } + probaEl = mlResponseSingleTrack.getModelOutput(inputFeatures, pbin)[1]; // 0: hadron, 1:electron } emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), @@ -566,6 +574,7 @@ struct skimmerPrimaryElectronQC { fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), trackParCov.getP(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(trackParCov.getTgl()))); fRegistry.fill(HIST("Track/hMeanClusterSizeITSib"), trackParCov.getP(), static_cast(total_cluster_size_ib) / static_cast(nl_ib) * std::cos(std::atan(trackParCov.getTgl()))); fRegistry.fill(HIST("Track/hMeanClusterSizeITSob"), trackParCov.getP(), static_cast(total_cluster_size_ob) / static_cast(nl_ob) * std::cos(std::atan(trackParCov.getTgl()))); + fRegistry.fill(HIST("Track/hProbElBDT"), track.tpcInnerParam(), probaEl); } } } @@ -607,7 +616,6 @@ struct skimmerPrimaryElectronQC { std::vector> stored_trackIds; Filter trackFilter = trackcut.minpt < o2::aod::track::pt && nabs(o2::aod::track::eta) < trackcut.maxeta && o2::aod::track::itsChi2NCl < trackcut.maxchi2its && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; - Filter pidFilter = trackcut.minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < trackcut.maxTPCNsigmaEl; using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; @@ -642,15 +650,6 @@ struct skimmerPrimaryElectronQC { } } - // if (isDielectronFromPi0(collision, pos, ele)) { - // if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele)) ) { - // fillTrackTable(collision, ele); - // } - // if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos)) ) { - // fillTrackTable(collision, pos); - // } - // } - } // end of ULS pairing } // end of collision loop @@ -690,15 +689,6 @@ struct skimmerPrimaryElectronQC { } } - // if (isDielectronFromPi0(collision, pos, ele)) { - // if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele)) ) { - // fillTrackTable(collision, ele); - // } - // if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos)) ) { - // fillTrackTable(collision, pos); - // } - // } - } // end of ULS pairing } // end of collision loop @@ -741,15 +731,6 @@ struct skimmerPrimaryElectronQC { } } - // if (isDielectronFromPi0(collision, pos, ele)) { - // if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele)) ) { - // fillTrackTable(collision, ele); - // } - // if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos)) ) { - // fillTrackTable(collision, pos); - // } - // } - } // end of ULS pairing } // end of collision loop diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx index b35d73698e7..2cd479429bd 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx @@ -183,7 +183,8 @@ struct TreeCreatorElectronMLDDA { Configurable cfg_min_cospa{"cfg_min_cospa", 0.9998, "min cospa for v0"}; Configurable cfg_max_dcadau{"cfg_max_dcadau", 0.1, "max distance between 2 legs for v0"}; - Configurable cfg_min_qt_strangeness{"cfg_min_qt_strangeness", 0.015, "min qt for Lambda and K0S"}; + Configurable cfg_min_qt_strangeness{"cfg_min_qt_strangeness", 0.02, "min qt for Lambda and K0S"}; + Configurable cfg_min_qt_k0s{"cfg_min_qt_k0s", 0.11, "min qt for K0S"}; Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; @@ -797,28 +798,30 @@ struct TreeCreatorElectronMLDDA { registry.fill(HIST("V0/hAP"), v0.alpha(), v0.qtarm()); if (v0cuts.cfg_min_qt_strangeness < v0.qtarm()) { - if (!(v0cuts.cfg_min_mass_lambda_veto < v0.mLambda() && v0.mLambda() < v0cuts.cfg_max_mass_lambda_veto) && !(v0cuts.cfg_min_mass_lambda_veto < v0.mAntiLambda() && v0.mAntiLambda() < v0cuts.cfg_max_mass_lambda_veto)) { - if ((isPionTight(pos) && isSelectedV0LegTight(collision, pos)) && (isPion(neg) && isSelectedV0Leg(collision, neg))) { - if (!tightv0cuts.requireTOF_for_tagging || pos.hasTOF()) { - registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); - if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.tpcInnerParam(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.tpcInnerParam(), neg.beta()); - fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + if (v0cuts.cfg_min_qt_k0s < v0.qtarm()) { + if (!(v0cuts.cfg_min_mass_lambda_veto < v0.mLambda() && v0.mLambda() < v0cuts.cfg_max_mass_lambda_veto) && !(v0cuts.cfg_min_mass_lambda_veto < v0.mAntiLambda() && v0.mAntiLambda() < v0cuts.cfg_max_mass_lambda_veto)) { + if ((isPionTight(pos) && isSelectedV0LegTight(collision, pos)) && (isPion(neg) && isSelectedV0Leg(collision, neg))) { + if (!tightv0cuts.requireTOF_for_tagging || pos.hasTOF()) { + registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); + if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.tpcInnerParam(), neg.beta()); + fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + } } } - } - if (isPion(pos) && isSelectedV0Leg(collision, pos) && isPionTight(neg) && isSelectedV0LegTight(collision, neg)) { - if (!tightv0cuts.requireTOF_for_tagging || neg.hasTOF()) { - registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); - if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.tpcInnerParam(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.tpcInnerParam(), pos.beta()); - fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + if (isPion(pos) && isSelectedV0Leg(collision, pos) && isPionTight(neg) && isSelectedV0LegTight(collision, neg)) { + if (!tightv0cuts.requireTOF_for_tagging || neg.hasTOF()) { + registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); + if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.tpcInnerParam(), pos.beta()); + fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + } } } - } - } // end of K0S + } // end of K0S + } if (!(v0cuts.cfg_min_mass_k0s_veto < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s_veto)) { if (isProton(pos) && isSelectedV0Leg(collision, pos) && isPionTight(neg) && isSelectedV0LegTight(collision, neg)) { @@ -842,6 +845,7 @@ struct TreeCreatorElectronMLDDA { } } // end of AntiLambda } + } // end of stangeness if (isElectronTight(pos) && isSelectedV0LegTight(collision, pos) && isElectron(neg) && isSelectedV0Leg(collision, neg)) { diff --git a/PWGEM/Dilepton/Tasks/CMakeLists.txt b/PWGEM/Dilepton/Tasks/CMakeLists.txt index fb0fb81fbcc..4e75843e48d 100644 --- a/PWGEM/Dilepton/Tasks/CMakeLists.txt +++ b/PWGEM/Dilepton/Tasks/CMakeLists.txt @@ -165,3 +165,9 @@ o2physics_add_dpl_workflow(mc-particle-predictions-otf SOURCES mcParticlePredictionsOTF.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(study-dcafitter + SOURCES studyDCAFitter.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + diff --git a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx index 323d82e7728..e77aefc7ae9 100644 --- a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx +++ b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx @@ -82,8 +82,9 @@ struct CreateResolutionMap { ConfigurableAxis ConfPhiGenBins{"ConfPhiGenBins", {72, 0, 2.f * M_PI}, "gen. eta bins at forward rapidity for output histograms"}; ConfigurableAxis ConfRelDeltaPtBins{"ConfRelDeltaPtBins", {200, -1.f, +1.f}, "rel. dpt for output histograms"}; - ConfigurableAxis ConfDeltaEtaBins{"ConfDeltaEtaBins", {200, -0.2f, +0.2f}, "deta bins for output histograms"}; - ConfigurableAxis ConfDeltaPhiBins{"ConfDeltaPhiBins", {200, -0.2f, +0.2f}, "dphi bins for output histograms"}; + ConfigurableAxis ConfDeltaEtaCBBins{"ConfDeltaEtaCBBins", {200, -0.5f, +0.5f}, "deta bins for output histograms"}; + ConfigurableAxis ConfDeltaEtaFWDBins{"ConfDeltaEtaFWDBins", {200, -0.5f, +0.5f}, "deta bins for output histograms"}; + ConfigurableAxis ConfDeltaPhiBins{"ConfDeltaPhiBins", {200, -0.5f, +0.5f}, "dphi bins for output histograms"}; Configurable cfgFillTHnSparse{"cfgFillTHnSparse", true, "fill THnSparse for output"}; Configurable cfgFillTH2{"cfgFillTH2", false, "fill TH2 for output"}; @@ -212,7 +213,8 @@ struct CreateResolutionMap { const AxisSpec axis_eta_fwd_gen{ConfEtaFWDGenBins, "#eta_{l}^{gen}"}; const AxisSpec axis_phi_gen{ConfPhiGenBins, "#varphi_{l}^{gen} (rad.)"}; const AxisSpec axis_dpt{ConfRelDeltaPtBins, "(p_{T,l}^{gen} - p_{T,l}^{rec})/p_{T,l}^{gen}"}; - const AxisSpec axis_deta{ConfDeltaEtaBins, "#eta_{l}^{gen} - #eta_{l}^{rec}"}; + const AxisSpec axis_deta_cb{ConfDeltaEtaCBBins, "#eta_{l}^{gen} - #eta_{l}^{rec}"}; + const AxisSpec axis_deta_fwd{ConfDeltaEtaFWDBins, "#eta_{l}^{gen} - #eta_{l}^{rec}"}; const AxisSpec axis_dphi{ConfDeltaPhiBins, "#varphi_{l}^{gen} - #varphi_{l}^{rec} (rad.)"}; const AxisSpec axis_charge_gen{3, -1.5, +1.5, "true sign"}; @@ -222,20 +224,26 @@ struct CreateResolutionMap { registry.add("Event/hGenID", "generator ID;generator ID;Number of mc collisions", kTH1F, {{7, -1.5, 5.5}}, true); } if (cfgFillTH2) { - registry.add("Electron/hPt", "rec. p_{T,l};p_{T,l} (GeV/c)", kTH1F, {{1000, 0, 10}}, false); - registry.add("Electron/hEtaPhi", "rec. #eta vs. #varphi;#varphi_{l} (rad.);#eta_{l}", kTH2F, {{90, 0, 2 * M_PI}, {100, -5, +5}}, false); + registry.add("Electron/hPt", "rec. p_{T,e};p_{T,e} (GeV/c)", kTH1F, {{1000, 0, 10}}, false); + registry.add("Electron/hEtaPhi", "rec. #eta vs. #varphi;#varphi_{e} (rad.);#eta_{e}", kTH2F, {{90, 0, 2 * M_PI}, {100, -5, +5}}, false); registry.add("Electron/Ptgen_RelDeltaPt", "resolution", kTH2F, {{axis_pt_gen}, {axis_dpt}}, true); - registry.add("Electron/Ptgen_DeltaEta", "resolution", kTH2F, {{axis_pt_gen}, {axis_deta}}, true); + registry.add("Electron/Ptgen_DeltaEta", "resolution", kTH2F, {{axis_pt_gen}, {axis_deta_cb}}, true); registry.add("Electron/Ptgen_DeltaPhi_Pos", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); registry.add("Electron/Ptgen_DeltaPhi_Neg", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); - registry.addClone("Electron/", "StandaloneMuon/"); - registry.addClone("Electron/", "GlobalMuon/"); + + registry.add("StandaloneMuon/hPt", "rec. p_{T,#mu};p_{T,#mu} (GeV/c)", kTH1F, {{1000, 0, 10}}, false); + registry.add("StandaloneMuon/hEtaPhi", "rec. #eta vs. #varphi;#varphi_{#mu} (rad.);#eta_{#mu}", kTH2F, {{90, 0, 2 * M_PI}, {100, -5, +5}}, false); + registry.add("StandaloneMuon/Ptgen_RelDeltaPt", "resolution", kTH2F, {{axis_pt_gen}, {axis_dpt}}, true); + registry.add("StandaloneMuon/Ptgen_DeltaEta", "resolution", kTH2F, {{axis_pt_gen}, {axis_deta_fwd}}, true); + registry.add("StandaloneMuon/Ptgen_DeltaPhi_Pos", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); + registry.add("StandaloneMuon/Ptgen_DeltaPhi_Neg", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); + registry.addClone("StandaloneMuon/", "GlobalMuon/"); } if (cfgFillTHnSparse) { - registry.add("Electron/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_cb_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); - registry.add("StandaloneMuon/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); - registry.add("GlobalMuon/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); + registry.add("Electron/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_cb_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta_cb, axis_dphi}, true); + registry.add("StandaloneMuon/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta_fwd, axis_dphi}, true); + registry.add("GlobalMuon/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta_fwd, axis_dphi}, true); } } @@ -592,7 +600,7 @@ struct CreateResolutionMap { return; } - if (!isSelectedMuon(pt, eta, rAtAbsorberEnd, pDCA, muon.chi2(), muon.trackType(), dcaXY)) { + if (!isSelectedMuon(pt, eta, rAtAbsorberEnd, pDCA, muon.chi2() / (2.f * (muon.nClusters() + nClustersMFT) - 5.f), muon.trackType(), dcaXY)) { return; } @@ -656,7 +664,7 @@ struct CreateResolutionMap { if (muoncuts.cfg_max_dcaxy_gl < dcaXY) { return false; } - if (chi2 < 0.f || muoncuts.cfg_max_chi2_gl < chi2) { + if (chi2 < 0.f || muoncuts.cfg_max_chi2_gl < chi2) { // chi2/ndf return false; } if (rAtAbsorberEnd < muoncuts.cfg_min_rabs_gl || muoncuts.cfg_max_rabs_gl < rAtAbsorberEnd) { diff --git a/PWGEM/Dilepton/Tasks/eventQC.cxx b/PWGEM/Dilepton/Tasks/eventQC.cxx index eb46e057ace..ee30bdd0e70 100644 --- a/PWGEM/Dilepton/Tasks/eventQC.cxx +++ b/PWGEM/Dilepton/Tasks/eventQC.cxx @@ -85,12 +85,12 @@ struct eventQC { struct : ConfigurableGroup { std::string prefix = "eventcut_group"; - Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; - Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; - Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; - Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; - Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; - Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", true, "require no ITS readout frame border in event cut"}; + Configurable cfgZvtxMin{"cfgZvtxMin", -1e+10, "min. Zvtx"}; + Configurable cfgZvtxMax{"cfgZvtxMax", 1e+10, "max. Zvtx"}; + Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; + Configurable cfgRequireFT0AND{"cfgRequireFT0AND", false, "require FT0AND in event cut"}; + Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; + Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. Configurable cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV. Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; @@ -201,13 +201,14 @@ struct eventQC { if (doprocessEventQC_SWT) { fRegistry.add("BC/hNcoll", "Number of collisions per triggered BC;N_{collision} per triggered BC", kTH1F, {{11, -0.5, +10.5}}, false); - fRegistry.add("BC/hDeltaT", "diff. in collision time per BC;#DeltaT_{coll} (ns)", kTH1F, {{500, -25, +25}}, false); - fRegistry.add("BC/hDeltaZ", "diff. in collision Z_{vtx} per BC;#DeltaZ_{vtx} (cm)", kTH1F, {{1000, -5, +5}}, false); - fRegistry.add("BC/hCorrNcontrib", "hMultNTracksPV;", kTH2F, {{axis_mult_ncontrib}, {axis_mult_ncontrib}}, false); - fRegistry.add("BC/Collision/hMultNTracksPV", "hMultNTracksPV;N_{track} to PV in |#eta| < 0.8", kTH1F, {{axis_mult_ncontrib08}}, false); + fRegistry.add("BC/Collision/hMultNTracksPV", "hMultNTracksPV;N_{track} to PV", kTH1F, {{axis_mult_ncontrib}}, false); fRegistry.add("BC/Collision/hMultFT0AFT0C", "hMultFT0AFT0C;mult. FT0A;mult. FT0C", kTH2F, {{axis_mult_ft0a}, {axis_mult_ft0c}}, false); fRegistry.add("BC/Collision/hMultFT0AFV0A", "hMultFT0AFV0A;mult. FT0A;mult. FV0A", kTH2F, {{axis_mult_ft0a}, {axis_mult_fv0a}}, false); fRegistry.add("BC/Collision/hMultFT0CFV0A", "hMultFT0CFV0A;mult. FT0C;mult. FV0A", kTH2F, {{axis_mult_ft0c}, {axis_mult_fv0a}}, false); + + fRegistry.add("perBC/hDeltaTZ", "#DeltaZ_{vtx} vs. #DeltaT of collisions per BC;#DeltaZ_{vtx} (cm);#DeltaT (ns)", kTH2F, {{100, -5, +5}, {50, -25, +25}}, false); + fRegistry.add("perBC/hCorrNcontrib", "hMultNTracksPV;", kTH2F, {{axis_mult_ncontrib}, {axis_mult_ncontrib}}, false); + // fRegistry.addClone("perBC/", "beyondBC/"); } // event info @@ -238,7 +239,8 @@ struct eventQC { if (cfgFillEvent) { fRegistry.add("Event/before/hZvtx", "vertex z; Z_{vtx} (cm)", kTH1F, {{100, -50, +50}}, false); - fRegistry.add("Event/before/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV in |#eta| < 0.8", kTH1F, {{axis_mult_ncontrib08}}, false); + fRegistry.add("Event/before/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", kTH1F, {{axis_mult_ncontrib}}, false); + fRegistry.add("Event/before/hMultNTracksPV08", "hMultNTracksPV08; N_{track} to PV in |#eta| < 0.8", kTH1F, {{axis_mult_ncontrib08}}, false); fRegistry.add("Event/before/hMultFT0AFT0C", "hMultFT0AFT0C;mult. FT0A;mult. FT0C", kTH2F, {{axis_mult_ft0a}, {axis_mult_ft0c}}, false); fRegistry.add("Event/before/hMultFT0AFV0A", "hMultFT0AFV0A;mult. FT0A;mult. FV0A", kTH2F, {{axis_mult_ft0a}, {axis_mult_fv0a}}, false); fRegistry.add("Event/before/hMultFT0CFV0A", "hMultFT0CFV0A;mult. FT0C;mult. FV0A", kTH2F, {{axis_mult_ft0c}, {axis_mult_fv0a}}, false); @@ -479,7 +481,8 @@ struct eventQC { } fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hZvtx"), collision.posZ()); - fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultNTracksPV"), collision.multNTracksPV()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultNTracksPV"), collision.numContrib()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultNTracksPV08"), collision.multNTracksPV()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0AFT0C"), collision.multFT0A(), collision.multFT0C()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0AFV0A"), collision.multFT0A(), collision.multFV0A()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0CFV0A"), collision.multFT0C(), collision.multFV0A()); @@ -740,7 +743,7 @@ struct eventQC { } template - bool isSelectedEvent(TCollision const& collision) + bool isSelectedCollision(TCollision const& collision) { if (eventcuts.cfgRequireSel8 && !collision.sel8()) { return false; @@ -838,38 +841,66 @@ struct eventQC { SliceCache cache; Preslice perCol = o2::aod::track::collisionId; - Preslice perBC = o2::aod::collision::bcId; + // Preslice perBC = o2::aod::collision::bcId; + PresliceUnsorted perFoundBC = aod::evsel::foundBCId; template void runQC(TBCs const& bcs, TCollisions const& collisions, TTracks const& tracks) { if constexpr (isTriggerAnalysis) { + // std::vector selectedCollisionIds; + // selectedCollisionIds.reserve(collisions.size()); + for (const auto& bc : bcs) { initCCDB(bc); if (!zorro.isSelected(bc.globalBC())) { // triggered BC continue; } - // if (!bc.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { - // continue; - // } - - const auto& collisions_per_bc = collisions.sliceBy(perBC, bc.globalIndex()); + // const auto& collisions_per_bc = collisions.sliceBy(perBC, bc.globalIndex()); + const auto& collisions_per_bc = collisions.sliceBy(perFoundBC, bc.globalIndex()); fRegistry.fill(HIST("BC/hNcoll"), collisions_per_bc.size()); for (const auto& collision : collisions_per_bc) { - fRegistry.fill(HIST("BC/Collision/hMultNTracksPV"), collision.multNTracksPV()); + if (!isSelectedCollision(collision)) { + continue; + } + + fRegistry.fill(HIST("BC/Collision/hMultNTracksPV"), collision.numContrib()); fRegistry.fill(HIST("BC/Collision/hMultFT0AFT0C"), collision.multFT0A(), collision.multFT0C()); fRegistry.fill(HIST("BC/Collision/hMultFT0AFV0A"), collision.multFT0A(), collision.multFV0A()); fRegistry.fill(HIST("BC/Collision/hMultFT0CFV0A"), collision.multFT0C(), collision.multFV0A()); + // selectedCollisionIds.emplace_back(collision.globalIndex()); } for (const auto& [col1, col2] : combinations(CombinationsStrictlyUpperIndexPolicy(collisions_per_bc, collisions_per_bc))) { - fRegistry.fill(HIST("BC/hDeltaZ"), col1.posZ() - col2.posZ()); - fRegistry.fill(HIST("BC/hDeltaT"), col1.collisionTime() - col2.collisionTime()); - fRegistry.fill(HIST("BC/hCorrNcontrib"), col1.numContrib(), col2.numContrib()); + if (!isSelectedCollision(col1) || !isSelectedCollision(col2)) { + continue; + } + fRegistry.fill(HIST("perBC/hDeltaTZ"), col1.posZ() - col2.posZ(), col1.collisionTime() - col2.collisionTime()); + fRegistry.fill(HIST("perBC/hCorrNcontrib"), col1.numContrib(), col2.numContrib()); } // end of pairing } // end of bc loop - } + + // for (const auto& collisionId1 : selectedCollisionIds) { + // const auto& col1 = collisions.rawIteratorAt(collisionId1); + // for (const auto& col2 : collisions) { + // if (!isSelectedCollision(col2)) { + // continue; + // } + + // const auto& bc1 = col1.template bc_as(); // don't use foundBC for CEFP. + // const auto& bc2 = col2.template bc_as(); // don't use foundBC for CEFP. + // if (bc1.globalBC() == bc2.globalBC()) { + // continue; + // } + // fRegistry.fill(HIST("beyondBC/hDeltaTZ"), col1.posZ() - col2.posZ(), col1.collisionTime() - col2.collisionTime()); + // fRegistry.fill(HIST("beyondBC/hCorrNcontrib"), col1.numContrib(), col2.numContrib()); + // } // end of all collision loop + // } // end of selected collision loop + + // selectedCollisionIds.clear(); + // selectedCollisionIds.shrink_to_fit(); + } // end of trigger QC for (const auto& collision : collisions) { if constexpr (isTriggerAnalysis) { @@ -892,7 +923,7 @@ struct eventQC { if (cfgFillEvent) { fillEventInfo<0>(collision); } - if (!isSelectedEvent(collision)) { + if (!isSelectedCollision(collision)) { continue; } if (cfgFillEvent) { diff --git a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx b/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx index d3a12ec6481..711bcc72c48 100644 --- a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx +++ b/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx @@ -317,30 +317,42 @@ struct prefilterDielectron { fDielectronCut.SetTOFNsigmaElRange(dielectroncuts.cfg_min_TOFNsigmaEl, dielectroncuts.cfg_max_TOFNsigmaEl); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - static constexpr int nClassesMl = 2; - const std::vector cutDirMl = {o2::cuts_ml::CutSmaller, o2::cuts_ml::CutNot}; - const std::vector labelsClasses = {"Signal", "Background"}; - const uint32_t nBinsMl = dielectroncuts.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] = dielectroncuts.cutsMl.value[i]; - cutsMlArr[i][1] = 0.; + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMl.value[i]); } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (dielectroncuts.loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); } - mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); - mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); - - fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + + // static constexpr int nClassesMl = 2; + // const std::vector cutDirMl = {o2::cuts_ml::CutSmaller, o2::cuts_ml::CutNot}; + // const std::vector labelsClasses = {"Signal", "Background"}; + // const uint32_t nBinsMl = dielectroncuts.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] = dielectroncuts.cutsMl.value[i]; + // cutsMlArr[i][1] = 0.; + // } + // o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + // mlResponseSingleTrack.configure(dielectroncuts.binsMl.value, cutsMl, cutDirMl, nClassesMl); + // if (dielectroncuts.loadModelsFromCCDB) { + // ccdbApi.init(ccdburl); + // mlResponseSingleTrack.setModelPathsCCDB(dielectroncuts.onnxFileNames.value, ccdbApi, dielectroncuts.onnxPathsCCDB.value, dielectroncuts.timestampCCDB.value); + // } else { + // mlResponseSingleTrack.setModelPathsLocal(dielectroncuts.onnxFileNames.value); + // } + // mlResponseSingleTrack.cacheInputFeaturesIndices(dielectroncuts.namesInputFeatures); + // mlResponseSingleTrack.cacheBinningIndex(dielectroncuts.nameBinningFeature); + // mlResponseSingleTrack.init(dielectroncuts.enableOptimizations.value); + + // fDielectronCut.SetPIDMlResponse(&mlResponseSingleTrack); } // end of PID ML } diff --git a/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx b/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx new file mode 100644 index 00000000000..2bdba06ace6 --- /dev/null +++ b/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx @@ -0,0 +1,973 @@ +// 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 studyDCAFitter.cxx +/// \brief a task to study tagging e from charm hadron decays in MC +/// \author daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "PWGEM/Dilepton/Utils/PairUtilities.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TableHelper.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Math/Vector4D.h" + +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::physics; +using namespace o2::aod::pwgem::dilepton::utils::mcutil; +using namespace o2::aod::pwgem::dilepton::utils::pairutil; + +struct studyDCAFitter { + using MyCollisions = soa::Join; + + using MyTracks = soa::Join; + + struct DielectronAtSV { // ee pair at SV + bool isfound{false}; + float mass{-999.f}; + float pt{-999.f}; + float dca2legs{-999.f}; + float cospa{-999.f}; + float lxy{-999.f}; + float lz{-999.f}; + float lxyz = std::sqrt(std::pow(lxy, 2) + std::pow(lz, 2)); + }; + + // Configurables + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; + Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; + Configurable d_UseAbsDCA{"d_UseAbsDCA", true, "Use Abs DCAs"}; + Configurable d_UseWeightedPCA{"d_UseWeightedPCA", false, "Vertices use cov matrices"}; + + struct : ConfigurableGroup { + std::string prefix = "electroncut"; + Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.05, "min pT for single track"}; + Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; + Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.9, "min eta for single track"}; + Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.9, "max eta for single track"}; + Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; + Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 80, "min ncrossed rows"}; + Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; + Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 3, "min ncluster itsib"}; + Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; + Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; + + Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2, "min TPC n sigma el inclusion"}; + Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3, "max TPC n sigma el inclusion"}; + Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -1e+10, "min TPC n sigma pi exclusion"}; + Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3, "max TPC n sigma pi exclusion"}; + Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3, "min TOF n sigma el inclusion"}; + Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3, "max TOF n sigma el inclusion"}; + } electroncut; + + struct : ConfigurableGroup { + std::string prefix = "svcut"; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.999, "min cospa"}; + Configurable cfg_max_dca2legs{"cfg_max_dca2legs", 0.1, "max distance between 2 legs"}; + } svcut; + + Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; + Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; + Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; + Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; + Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; + + Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; + + HistogramRegistry fRegistry{"fRegistry"}; + static constexpr std::string_view hadron_names[6] = {"LF/", "Jpsi/", "D0/", "Dpm/", "Ds/", "Lc/"}; + static constexpr std::string_view pair_names[3] = {"e_Kpm/", "e_K0S/", "e_Lambda/"}; + static constexpr std::string_view hTypes[4] = {"findable/", "correct/", "fake/", "miss/"}; + static constexpr std::string_view promptTypes[2] = {"prompt/", "nonprompt/"}; + + void init(o2::framework::InitContext&) + { + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + fitter.setPropagateToPCA(true); + fitter.setMaxR(5.f); + fitter.setMinParamChange(1e-3); + fitter.setMinRelChi2Change(0.9); + fitter.setMaxDZIni(1e9); + fitter.setMaxChi2(1e9); + fitter.setUseAbsDCA(d_UseAbsDCA); + fitter.setWeightedFinalPCA(d_UseWeightedPCA); + fitter.setMatCorrType(matCorr); + + addHistograms(); + } + + int mRunNumber; + float d_bz; + Service ccdb; + // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; + o2::base::MatLayerCylSet* lut = nullptr; + o2::vertexing::DCAFitterN<2> fitter; + o2::dataformats::DCA mDcaInfoCov; + o2::dataformats::VertexBase mVtx; + + template + void initCCDB(TBC const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + + // load matLUT for this timestamp + if (!lut) { + LOG(info) << "Loading material look-up table for timestamp: " << bc.timestamp(); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->getForTimeStamp(lutPath, bc.timestamp())); + } else { + LOG(info) << "Material look-up table already in place. Not reloading."; + } + + // In case override, don't proceed, please - no CCDB access required + if (d_bz_input > -990) { + d_bz = d_bz_input; + o2::parameters::GRPMagField grpmag; + if (std::fabs(d_bz) > 1e-5) { + grpmag.setL3Current(30000.f / (d_bz / 5.0f)); + } + o2::base::Propagator::initFieldFromGRP(&grpmag); + o2::base::Propagator::Instance()->setMatLUT(lut); + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + mRunNumber = bc.runNumber(); + return; + } + + auto run3grp_timestamp = bc.timestamp(); + o2::parameters::GRPObject* grpo = 0x0; + o2::parameters::GRPMagField* grpmag = 0x0; + if (!skipGRPOquery) { + grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + } + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + o2::base::Propagator::Instance()->setMatLUT(lut); + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + // Fetch magnetic field from ccdb for current collision + d_bz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + } else { + grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + o2::base::Propagator::Instance()->setMatLUT(lut); + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + + // Fetch magnetic field from ccdb for current collision + 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"; + } + mRunNumber = bc.runNumber(); + fitter.setBz(d_bz); + } + + void addHistograms() + { + auto hCollisionCounter = fRegistry.add("Event/hCollisionCounter", "collision counter", kTH1D, {{5, -0.5f, 4.5f}}, false); + hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); + hCollisionCounter->GetXaxis()->SetBinLabel(2, "accepted"); + + fRegistry.add("Event/hZvtx", "vertex z; Z_{vtx} (cm)", kTH1F, {{100, -50, +50}}, false); + fRegistry.add("Event/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); + fRegistry.add("Event/hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); + fRegistry.add("Event/hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", kTH2F, {{200, 0, 200000}, {60, 0, 60000}}, false); + fRegistry.add("Event/hCentFT0A", "hCentFT0A;centrality FT0A (%)", kTH1F, {{110, 0, 110}}, false); + fRegistry.add("Event/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1F, {{110, 0, 110}}, false); + fRegistry.add("Event/hCentFT0M", "hCentFT0M;centrality FT0M (%)", kTH1F, {{110, 0, 110}}, false); + fRegistry.add("Event/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); + fRegistry.add("Event/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); + + // for pairs + fRegistry.add("Pair/PV/Data/uls/hs", "hs;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);", kTHnSparseF, {{500, 0, 5}, {100, 0, 10}, {100, 0, 10}}, true); + fRegistry.addClone("Pair/PV/Data/uls/", "Pair/PV/Data/lspp/"); + fRegistry.addClone("Pair/PV/Data/uls/", "Pair/PV/Data/lsmm/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/PromptPhi/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/NonPromptPhi/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/PromptOmega/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/NonPromptOmega/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/PromptJpsi/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/NonPromptJpsi/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/c2e_c2e/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/b2e_b2e/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/b2c2e_b2c2e/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/b2c2e_b2e_sameb/"); + fRegistry.addClone("Pair/PV/Data/", "Pair/PV/MC/b2c2e_b2e_diffb/"); + + fRegistry.add("Pair/SV/Data/uls/hs", "hs;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);L_{xy} m_{ee}/p_{T,ee} (mm);", kTHnSparseF, {{500, 0, 5}, {100, 0, 10}, {200, -10, 10}}, true); + fRegistry.add("Pair/SV/Data/uls/hCosPA", "cosPA;cosPA;", kTH1F, {{200, -1, 1}}, false); + fRegistry.add("Pair/SV/Data/uls/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs (cm);", kTH1F, {{100, 0, 0.1}}, false); + fRegistry.addClone("Pair/SV/Data/uls/", "Pair/SV/Data/lspp/"); + fRegistry.addClone("Pair/SV/Data/uls/", "Pair/SV/Data/lsmm/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/PromptPhi/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/NonPromptPhi/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/PromptOmega/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/NonPromptOmega/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/PromptJpsi/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/NonPromptJpsi/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/c2e_c2e/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/b2e_b2e/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/b2c2e_b2c2e/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/b2c2e_b2e_sameb/"); + fRegistry.addClone("Pair/SV/Data/", "Pair/SV/MC/b2c2e_b2e_diffb/"); + } + + template + bool isElectron(TTrack const& track) + { + // TOFif + bool is_el_included_TPC = electroncut.cfg_min_TPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < electroncut.cfg_max_TPCNsigmaEl; + bool is_el_included_TOF = track.hasTOF() ? (electroncut.cfg_min_TOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < electroncut.cfg_max_TOFNsigmaEl) : true; + return is_el_included_TPC && is_el_included_TOF; + } + + template + bool isSelectedTrack(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) + { + + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + + if (trackParCov.getPt() < electroncut.cfg_min_pt_track || electroncut.cfg_max_pt_track < trackParCov.getPt()) { + return false; + } + + if (trackParCov.getEta() < electroncut.cfg_min_eta_track || electroncut.cfg_max_eta_track < trackParCov.getEta()) { + return false; + } + + if (std::fabs(dcaXY) > electroncut.cfg_max_dcaxy) { + return false; + } + + if (std::fabs(dcaZ) > electroncut.cfg_max_dcaz) { + return false; + } + + if (track.itsChi2NCl() > electroncut.cfg_max_chi2its) { + return false; + } + + if (track.itsNCls() < electroncut.cfg_min_ncluster_its) { + return false; + } + + if (track.itsNClsInnerBarrel() < electroncut.cfg_min_ncluster_itsib) { + return false; + } + + if (track.tpcChi2NCl() > electroncut.cfg_max_chi2tpc) { + return false; + } + + if (track.tpcNClsFound() < electroncut.cfg_min_ncluster_tpc) { + return false; + } + + if (track.tpcNClsCrossedRows() < electroncut.cfg_min_ncrossedrows_tpc) { + return false; + } + + if (track.tpcCrossedRowsOverFindableCls() < electroncut.cfg_min_cr2findable_ratio_tpc) { + return false; + } + + if (track.tpcFractionSharedCls() > electroncut.cfg_max_frac_shared_clusters_tpc) { + return false; + } + + return true; + } + + template + void fillEventHistograms(TCollision const& collision) + { + fRegistry.fill(HIST("Event/hZvtx"), collision.posZ()); + fRegistry.fill(HIST("Event/hMultNTracksPV"), collision.multNTracksPV()); + fRegistry.fill(HIST("Event/hMultNTracksPVeta1"), collision.multNTracksPVeta1()); + fRegistry.fill(HIST("Event/hMultFT0"), collision.multFT0A(), collision.multFT0C()); + fRegistry.fill(HIST("Event/hCentFT0A"), collision.centFT0A()); + fRegistry.fill(HIST("Event/hCentFT0C"), collision.centFT0C()); + fRegistry.fill(HIST("Event/hCentFT0M"), collision.centFT0M()); + fRegistry.fill(HIST("Event/hCentFT0CvsMultNTracksPV"), collision.centFT0C(), collision.multNTracksPV()); + fRegistry.fill(HIST("Event/hMultFT0CvsMultNTracksPV"), collision.multFT0C(), collision.multNTracksPV()); + } + + template + void fillElectronHistograms(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) + { + if (std::find(used_electronIds.begin(), used_electronIds.end(), std::make_pair(findId, track.globalIndex())) == used_electronIds.end()) { + float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); + fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("electron/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("electron/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); + fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("electron/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hTOFbeta"), trackParCov.getP(), track.beta()); + used_electronIds.emplace_back(std::make_pair(findId, track.globalIndex())); + } + } + + float dca3DinSigmaOTF(const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) + { + float det = cYY * cZZ - cZY * cZY; // determinant + if (det < 0) { + return 999.f; + } else { + return std::sqrt(std::fabs((dcaXY * dcaXY * cZZ + dcaZ * dcaZ * cYY - 2. * dcaXY * dcaZ * cZY) / det / 2.)); // dca 3d in sigma + } + } + + template + int FindLF(TTrack const& posmc, TTrack const& negmc, TMCParticles const& mcparticles) + { + int arr[] = { + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 22, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 111, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 221, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 331, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 113, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 223, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 333, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 443, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 100443, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 553, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 100553, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 200553, mcparticles), + FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 300553, mcparticles)}; + int size = sizeof(arr) / sizeof(*arr); + int max = *std::max_element(arr, arr + size); + return max; + } + + template + void runPairingAtPV(TTrack const& t1, TTrack const& t2, TMCParticles const& mcParticles) + { + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov1 = getTrackParCov(t1); + trackParCov1.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov1, 2.f, matCorr, &mDcaInfoCov); + float dcaXY1 = mDcaInfoCov.getY(); + float dcaZ1 = mDcaInfoCov.getZ(); + + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov2 = getTrackParCov(t2); + trackParCov2.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov2, 2.f, matCorr, &mDcaInfoCov); + float dcaXY2 = mDcaInfoCov.getY(); + float dcaZ2 = mDcaInfoCov.getZ(); + + ROOT::Math::PtEtaPhiMVector v1(trackParCov1.getPt(), trackParCov1.getEta(), trackParCov1.getPhi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(trackParCov2.getPt(), trackParCov2.getEta(), trackParCov2.getPhi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float dca3DinSigma1 = dca3DinSigmaOTF(dcaXY1, dcaZ1, trackParCov1.getSigmaY2(), trackParCov1.getSigmaZ2(), trackParCov1.getSigmaZY()); + float dca3DinSigma2 = dca3DinSigmaOTF(dcaXY2, dcaZ2, trackParCov2.getSigmaY2(), trackParCov2.getSigmaZ2(), trackParCov2.getSigmaZY()); + float pair_dca = pairDCAQuadSum(dca3DinSigma1, dca3DinSigma2); + + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/Data/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/Data/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/Data/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + + if constexpr (isMC) { + const auto& t1mc = t1.template mcParticle_as(); + const auto& t2mc = t2.template mcParticle_as(); + if (std::abs(t1mc.pdgCode()) != 11) { + return; + } + if (!(t1mc.isPhysicalPrimary() || t1mc.producedByGenerator())) { + return; + } + if (std::abs(t2mc.pdgCode()) != 11) { + return; + } + if (!(t2mc.isPhysicalPrimary() || t2mc.producedByGenerator())) { + return; + } + // const auto& mp1 = t1mc.template mothers_first_as(); // mother particle of t1 + // const auto& mp2 = t2mc.template mothers_first_as(); // mother particle of t2 + int mcCommonMotherid = FindLF(t1mc, t2mc, mcParticles); + int hfee_type = IsHF(t1mc, t2mc, mcParticles); + + if (mcCommonMotherid > -1) { + const auto cmp = mcParticles.rawIteratorAt(mcCommonMotherid); + switch (std::abs(cmp.pdgCode())) { + case 223: + if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/PromptOmega/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/PromptOmega/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/PromptOmega/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + } else { // nonprompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/NonPromptOmega/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/NonPromptOmega/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/NonPromptOmega/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + } + break; + case 333: + if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/PromptPhi/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/PromptPhi/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/PromptPhi/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + } else { // nonprompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/NonPromptPhi/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/NonPromptPhi/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/NonPromptPhi/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + } + break; + case 443: + if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/PromptJpsi/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/PromptJpsi/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/PromptJpsi/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + } else { // nonprompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/NonPromptJpsi/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/NonPromptJpsi/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/NonPromptJpsi/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + } + break; + default: + break; + } // end of switch for LF + } else if (hfee_type > -1) { + switch (hfee_type) { + case static_cast(EM_HFeeType::kCe_Ce): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/c2e_c2e/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/c2e_c2e/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/c2e_c2e/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + break; + case static_cast(EM_HFeeType::kBe_Be): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/b2e_b2e/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/b2e_b2e/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/b2e_b2e/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + break; + case static_cast(EM_HFeeType::kBCe_BCe): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2c2e/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2c2e/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2c2e/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + break; + case static_cast(EM_HFeeType::kBCe_Be_SameB): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2e_sameb/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2e_sameb/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2e_sameb/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + break; + case static_cast(EM_HFeeType::kBCe_Be_DiffB): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2e_diffb/uls/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 1) { // LS+diff + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2e_diffb/lspp/hs"), v12.M(), v12.Pt(), pair_dca); + } else if constexpr (signType == 2) { // LS-diff + fRegistry.fill(HIST("Pair/PV/MC/b2c2e_b2e_diffb/lsmm/hs"), v12.M(), v12.Pt(), pair_dca); + } + break; + + default: + break; + } // end of switch for HFee + } // end of HFee + } // end of isMC + } + + template + void runSVFinder(TCollision const& collision, TTrack const& t1, TTrack const& t2, TMCParticles const& mcParticles) + { + DielectronAtSV eeatsv; + + auto trackParCov1 = getTrackParCov(t1); + trackParCov1.setPID(o2::track::PID::Electron); + auto trackParCov2 = getTrackParCov(t2); + trackParCov2.setPID(o2::track::PID::Electron); + + std::array pVtx = {collision.posX(), collision.posY(), collision.posZ()}; + std::array svpos = {0.}; // secondary vertex position + std::array pvec0 = {0.}; + std::array pvec1 = {0.}; + + int nCand = 0; + try { + nCand = fitter.process(trackParCov1, trackParCov2); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call!"; + return; + } + if (nCand == 0) { + return; + } + + fitter.propagateTracksToVertex(); // propagate e and K to D vertex + if (!fitter.isPropagateTracksToVertexDone()) { + return; + } + const auto& vtx = fitter.getPCACandidate(); + for (int i = 0; i < 3; i++) { + svpos[i] = vtx[i]; + } + fitter.getTrack(0).getPxPyPzGlo(pvec0); + fitter.getTrack(1).getPxPyPzGlo(pvec1); + std::array pvecSum = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; + + float cpa = RecoDecay::cpa(pVtx, svpos, pvecSum); + float dca2legs = std::sqrt(fitter.getChi2AtPCACandidate()); + // float lxy = std::sqrt(std::pow(svpos[0] - collision.posX(), 2) + std::pow(svpos[1] - collision.posY(), 2)); // in cm + float lz = std::fabs(svpos[2] - collision.posZ()); // in cm + + float meeAtSV = RecoDecay::m(std::array{pvec0, pvec1}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); + float pteeAtSV = RecoDecay::sqrtSumOfSquares(pvecSum[0], pvecSum[1]); + float lxy = RecoDecay::dotProd(std::array{pvecSum[0], pvecSum[1]}, std::array{svpos[0] - collision.posX(), svpos[1] - collision.posY()}) / pteeAtSV; + float ppdl = lxy * 1e-2 * meeAtSV / pteeAtSV * 1e+3; // pseudo-proper decay length in mm + + if (cpa < svcut.cfg_min_cospa || svcut.cfg_max_dca2legs < dca2legs) { + return; + } + + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/Data/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/Data/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/Data/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/Data/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/Data/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/Data/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/Data/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/Data/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/Data/lsmm/hDCA2Legs"), dca2legs); + } + + if constexpr (isMC) { + const auto& t1mc = t1.template mcParticle_as(); + const auto& t2mc = t2.template mcParticle_as(); + if (std::abs(t1mc.pdgCode()) != 11) { + return; + } + if (!(t1mc.isPhysicalPrimary() || t1mc.producedByGenerator())) { + return; + } + if (std::abs(t2mc.pdgCode()) != 11) { + return; + } + if (!(t2mc.isPhysicalPrimary() || t2mc.producedByGenerator())) { + return; + } + // const auto& mp1 = t1mc.template mothers_first_as(); // mother particle of t1 + // const auto& mp2 = t2mc.template mothers_first_as(); // mother particle of t2 + int mcCommonMotherid = FindLF(t1mc, t2mc, mcParticles); + int hfee_type = IsHF(t1mc, t2mc, mcParticles); + + if (mcCommonMotherid > -1) { + const auto cmp = mcParticles.rawIteratorAt(mcCommonMotherid); + switch (cmp.pdgCode()) { + case 223: + if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptOmega/lsmm/hDCA2Legs"), dca2legs); + } + } else { // nonprompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptOmega/lsmm/hDCA2Legs"), dca2legs); + } + } + break; + case 333: + if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptPhi/lsmm/hDCA2Legs"), dca2legs); + } + } else { // nonprompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptPhi/lsmm/hDCA2Legs"), dca2legs); + } + } + break; + case 443: + if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/PromptJpsi/lsmm/hDCA2Legs"), dca2legs); + } + } else { // nonprompt + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/NonPromptJpsi/lsmm/hDCA2Legs"), dca2legs); + } + } + break; + default: + break; + } // end of switch for LF + } else if (hfee_type > -1) { + switch (hfee_type) { + case static_cast(EM_HFeeType::kCe_Ce): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/c2e_c2e/lsmm/hDCA2Legs"), dca2legs); + } + break; + case static_cast(EM_HFeeType::kBe_Be): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2e_b2e/lsmm/hDCA2Legs"), dca2legs); + } + break; + case static_cast(EM_HFeeType::kBCe_BCe): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2c2e/lsmm/hDCA2Legs"), dca2legs); + } + break; + case static_cast(EM_HFeeType::kBCe_Be_SameB): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS++ + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-- + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_sameb/lsmm/hDCA2Legs"), dca2legs); + } + break; + case static_cast(EM_HFeeType::kBCe_Be_DiffB): + if constexpr (signType == 0) { // ULS + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/uls/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/uls/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/uls/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 1) { // LS+diff + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/lspp/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/lspp/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/lspp/hDCA2Legs"), dca2legs); + } else if constexpr (signType == 2) { // LS-diff + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/lsmm/hs"), meeAtSV, pteeAtSV, ppdl); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/lsmm/hCosPA"), cpa); + fRegistry.fill(HIST("Pair/SV/MC/b2c2e_b2e_diffb/lsmm/hDCA2Legs"), dca2legs); + } + break; + + default: + break; + } // end of switch for HFee + } // end of HFee + } // end of isMC + + eeatsv.isfound = true; + eeatsv.mass = meeAtSV; + eeatsv.pt = pteeAtSV; + eeatsv.cospa = cpa; + eeatsv.dca2legs = dca2legs; + eeatsv.lxy = lxy; + eeatsv.lz = lz; + return; + } + + template + void run(TBCs const&, TCollisions const& collisions, TTracks const& tracks, TTrackAssoc const& trackIndices, TMCCollisions const&, TMCParticles const& mcParticles) + { + used_electronIds.reserve(tracks.size()); + + for (const auto& collision : collisions) { + const auto& bc = collision.template foundBC_as(); + initCCDB(bc); + fRegistry.fill(HIST("Event/hCollisionCounter"), 0); + + const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + fRegistry.fill(HIST("Event/hCollisionCounter"), 1); + fillEventHistograms(collision); + + const auto& trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); + electronIds.reserve(trackIdsThisCollision.size()); + positronIds.reserve(trackIdsThisCollision.size()); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + for (const auto& trackId : trackIdsThisCollision) { + const auto& track = trackId.template track_as(); + if (!track.hasITS() || !track.hasTPC()) { + continue; + } + + if constexpr (isMC) { + if (!track.has_mcParticle()) { + continue; + } + const auto& mctrack = track.template mcParticle_as(); + const auto& mcCollision = mctrack.template mcCollision_as(); + if (cfgEventGeneratorType >= 0 && mcCollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + if (!mctrack.has_mothers()) { + continue; + } + } + + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + + if (isSelectedTrack(track, trackParCov, dcaXY, dcaZ) && isElectron(track)) { + if (track.sign() > 0) { // positron + positronIds.emplace_back(trackId.trackId()); + } else { // electron + electronIds.emplace_back(trackId.trackId()); + } + } + } // end of track loop for electron selection + + for (const auto& posId : positronIds) { + const auto& pos = tracks.rawIteratorAt(posId); + for (const auto& eleId : electronIds) { + const auto& ele = tracks.rawIteratorAt(eleId); + runSVFinder(collision, pos, ele, mcParticles); + runPairingAtPV(pos, ele, mcParticles); + } // end of electron loop + } // end of positron loop + + for (const auto& posId1 : positronIds) { + const auto& pos1 = tracks.rawIteratorAt(posId1); + for (const auto& posId2 : positronIds) { + const auto& pos2 = tracks.rawIteratorAt(posId2); + if (pos1.globalIndex() == pos2.globalIndex()) { + continue; + } + runSVFinder(collision, pos1, pos2, mcParticles); + runPairingAtPV(pos1, pos2, mcParticles); + } // end of positron loop + } // end of positron loop + + for (const auto& eleId1 : electronIds) { + const auto& ele1 = tracks.rawIteratorAt(eleId1); + for (const auto& eleId2 : electronIds) { + const auto& ele2 = tracks.rawIteratorAt(eleId2); + if (ele1.globalIndex() == ele2.globalIndex()) { + continue; + } + runSVFinder(collision, ele1, ele2, mcParticles); + runPairingAtPV(ele1, ele2, mcParticles); + } // end of electron loop + } // end of electron loop + + electronIds.clear(); + electronIds.shrink_to_fit(); + positronIds.clear(); + positronIds.shrink_to_fit(); + } // end of collision loop + + used_electronIds.clear(); + used_electronIds.shrink_to_fit(); + } + + SliceCache cache; + Preslice perCol = o2::aod::track::collisionId; + + Filter collisionFilter_evsel = o2::aod::evsel::sel8 == true && (cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < cfgZvtxMax); + Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); + using FilteredMyCollisions = soa::Filtered; + + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + // Partition posTracks = o2::aod::track::signed1Pt > 0.f; + // Partition negTracks = o2::aod::track::signed1Pt < 0.f; + + std::vector electronIds; + std::vector positronIds; + std::vector> used_electronIds; // pair of hTypeId and electronId + + void processMC(FilteredMyCollisions const& collisions, aod::BCsWithTimestamps const& bcs, MyTracks const& tracks, aod::TrackAssoc const& trackIndices, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + run(bcs, collisions, tracks, trackIndices, mcCollisions, mcParticles); + } + PROCESS_SWITCH(studyDCAFitter, processMC, "processMC", true); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"study-dcafitter"})}; +} diff --git a/PWGEM/Dilepton/Tasks/taggingHFE.cxx b/PWGEM/Dilepton/Tasks/taggingHFE.cxx index b3098ef9774..4ff5224cde5 100644 --- a/PWGEM/Dilepton/Tasks/taggingHFE.cxx +++ b/PWGEM/Dilepton/Tasks/taggingHFE.cxx @@ -125,28 +125,10 @@ struct taggingHFE { Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; - Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2, "min n sigma el in TPC"}; - Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3, "max n sigma el in TPC"}; - Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3, "min n sigma el in TOF"}; - Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3, "max n sigma el in TOF"}; } loose_electroncut; struct : ConfigurableGroup { std::string prefix = "kaoncut"; - Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.05, "min pT for single track"}; - Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; - Configurable cfg_min_eta_track{"cfg_min_eta_track", -1.2, "min eta for single track"}; - Configurable cfg_max_eta_track{"cfg_max_eta_track", +1.2, "max eta for single track"}; - Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; - Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 40, "min ncrossed rows"}; - Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; - Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 4, "min ncluster its"}; - Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 1, "min ncluster itsib"}; - Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3, "min n sigma ka in TPC"}; 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"}; @@ -215,7 +197,7 @@ struct taggingHFE { Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; } eventcut; - Configurable cfgMeeMaxPF{"cfgMeeMaxPF", 0.08, "max mee for prefilter to reject pi0->ee and gamma->ee in LMR"}; + Configurable cfgMeeMaxPF{"cfgMeeMaxPF", 0.04, "max mee for prefilter to reject pi0->ee and gamma->ee in LMR"}; HistogramRegistry fRegistry{"fRegistry"}; static constexpr std::string_view hadron_names[6] = {"LF/", "Jpsi/", "D0/", "Dpm/", "Ds/", "Lc/"}; @@ -368,7 +350,7 @@ struct taggingHFE { fRegistry.add("Data/V0/hYPhi", "rapidity vs. #varphi of V0;#varphi (rad.);rapidity_{#Lambda}", kTH2F, {{90, 0, 2 * M_PI}, {80, -2, +2}}, false); fRegistry.add("Data/V0/hAP", "Ap plot;#alpha;q_{T} (GeV/c)", kTH2F, {{200, -1, 1}, {250, 0, 0.25}}, false); fRegistry.add("Data/V0/hLxy", "decay length from PV;L_{xy} (cm)", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Data/V0/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{100, 0.99, 1}}, false); + fRegistry.add("Data/V0/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{200, -1, 1}}, false); fRegistry.add("Data/V0/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); fRegistry.add("Data/V0/hMassK0S", "K0S mass;m_{#pi#pi} (GeV/c^{2})", kTH1F, {{100, 0.45, 0.55}}, false); fRegistry.add("Data/V0/hMassLambda", "Lambda mass;m_{p#pi^{-}} (GeV/c^{2})", kTH1F, {{100, 1.08, 1.18}}, false); @@ -377,7 +359,7 @@ struct taggingHFE { // for cascade fRegistry.add("Data/Cascade/hPt", "pT of V0;p_{T} (GeV/c)", kTH1F, {{100, 0, 10}}, false); fRegistry.add("Data/Cascade/hYPhi", "rapidity vs. #varphi of V0;#varphi (rad.);rapidity_{#Lambda}", kTH2F, {{90, 0, 2 * M_PI}, {80, -2, +2}}, false); - fRegistry.add("Data/Cascade/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{100, 0.99, 1}}, false); + fRegistry.add("Data/Cascade/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{200, -1, 1}}, false); fRegistry.add("Data/Cascade/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); fRegistry.add("Data/Cascade/hV0CosPA", "cosPA of V0 in cascade;cosine of pointing angle", kTH1F, {{100, 0.99, 1}}, false); fRegistry.add("Data/Cascade/hV0DCA2Legs", "distance between 2 legs at PCA of V0 in cascade;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); @@ -387,31 +369,31 @@ struct taggingHFE { fRegistry.add("Data/Cascade/hMassOmega", "#Omega mass;m_{#LambdaK} (GeV/c^{2})", kTH1F, {{100, 1.62, 1.72}}, false); // for e-L pair - fRegistry.add("Data/eL/RS/hs", "hs;m_{e#Lambda} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {500, 0, 0.5}}, false); - fRegistry.add("Data/eL/RS/hCosPA", "cos PA;cosPA", kTH1F, {{100, 0.99, 1.0}}, false); + fRegistry.add("Data/eL/RS/hs", "hs;m_{e#Lambda} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {100, 0, 1.0}}, false); + fRegistry.add("Data/eL/RS/hCosPA", "cos PA;cosPA", kTH1F, {{200, -1, 1}}, false); fRegistry.add("Data/eL/RS/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs at PCA (cm)", kTH1F, {{500, 0.0, 0.5}}, false); - fRegistry.add("Data/eL/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); - fRegistry.add("Data/eL/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eL/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{100, 0.0, 1}}, false); + fRegistry.add("Data/eL/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{100, 0.0, 1}}, false); fRegistry.addClone("Data/eL/RS/", "Data/eL/WS/"); // right and wrong sign fRegistry.addClone("Data/eL/RS/", "MC/eLfromPromptLcpm/"); fRegistry.addClone("Data/eL/RS/", "MC/eLfromNonPromptLcpm/"); // for e-Xi pair - fRegistry.add("Data/eXi/RS/hs", "hs;m_{e#Xi} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {500, 0, 0.5}}, false); - fRegistry.add("Data/eXi/RS/hCosPA", "cos PA;cosPA", kTH1F, {{100, 0.99, 1.0}}, false); + fRegistry.add("Data/eXi/RS/hs", "hs;m_{e#Xi} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.3, 3.3}, {100, 0, 10}, {100, 0, 10}, {100, 0, 1.0}}, false); + fRegistry.add("Data/eXi/RS/hCosPA", "cos PA;cosPA", kTH1F, {{200, -1, 1}}, false); fRegistry.add("Data/eXi/RS/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs at PCA (cm)", kTH1F, {{500, 0.0, 0.5}}, false); - fRegistry.add("Data/eXi/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); - fRegistry.add("Data/eXi/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eXi/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{100, 0.0, 1}}, false); + fRegistry.add("Data/eXi/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{100, 0.0, 1}}, false); fRegistry.addClone("Data/eXi/RS/", "Data/eXi/WS/"); // right and wrong sign fRegistry.addClone("Data/eXi/RS/", "MC/eXifromPromptXic0/"); fRegistry.addClone("Data/eXi/RS/", "MC/eXifromNonPromptXic0/"); // for e-Omega pair - fRegistry.add("Data/eOmega/RS/hs", "hs;m_{e#Omega} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {500, 0, 0.5}}, false); - fRegistry.add("Data/eOmega/RS/hCosPA", "cos PA;cosPA", kTH1F, {{100, 0.99, 1.0}}, false); + fRegistry.add("Data/eOmega/RS/hs", "hs;m_{e#Omega} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.6, 3.6}, {100, 0, 10}, {100, 0, 10}, {100, 0, 1.0}}, false); + fRegistry.add("Data/eOmega/RS/hCosPA", "cos PA;cosPA", kTH1F, {{200, -1, 1}}, false); fRegistry.add("Data/eOmega/RS/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs at PCA (cm)", kTH1F, {{500, 0.0, 0.5}}, false); - fRegistry.add("Data/eOmega/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); - fRegistry.add("Data/eOmega/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eOmega/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{100, 0.0, 1}}, false); + fRegistry.add("Data/eOmega/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{100, 0.0, 1}}, false); fRegistry.addClone("Data/eOmega/RS/", "Data/eOmega/WS/"); // right and wrong sign fRegistry.addClone("Data/eOmega/RS/", "MC/eOmegafromPromptOmegac0/"); fRegistry.addClone("Data/eOmega/RS/", "MC/eOmegafromNonPromptOmegac0/"); @@ -703,9 +685,10 @@ struct taggingHFE { float dcaZ = mDcaInfoCov.getZ(); float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); - if (isSelectedElectron(track, trackParCov, dcaXY, dcaZ)) { + if (!isSelectedElectron(track, trackParCov, dcaXY, dcaZ)) { return; } + fRegistry.fill(HIST("Data/electron/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); if constexpr (isMC) { const auto& mctrack = track.template mcParticle_as(); @@ -777,8 +760,6 @@ struct taggingHFE { } else if (pdg_mother == 5122) { // Lb0 fRegistry.fill(HIST("MC/eFromLb0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); } - } else { - fRegistry.fill(HIST("Data/electron/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); } } @@ -837,8 +818,9 @@ struct taggingHFE { eLpair.ptepv = trackParCov.getPt(); eLpair.dca3dinsigma = dca3DinSigma; - const std::array vertex = {v0.x(), v0.y(), v0.z()}; - const std::array momentum = {v0.px(), v0.py(), v0.pz()}; + const std::array vertex = {collision.posX(), collision.posY(), collision.posZ()}; + const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; + const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; std::array covV0 = {0.f}; constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component @@ -847,7 +829,7 @@ struct taggingHFE { covV0[i] = v0.positionCovMat()[i]; } - auto v0ParCov = o2::track::TrackParCov(vertex, momentum, covV0, 0, true); + auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); v0ParCov.setAbsCharge(0); v0ParCov.setPID(o2::track::PID::Lambda); @@ -906,8 +888,9 @@ struct taggingHFE { eCascPair.ptepv = trackParCov.getPt(); eCascPair.dca3dinsigma = dca3DinSigma; - const std::array vertex = {cascade.x(), cascade.y(), cascade.z()}; - const std::array momentum = {cascade.px(), cascade.py(), cascade.pz()}; + const std::array vertex = {collision.posX(), collision.posY(), collision.posZ()}; + const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; + const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; std::array covCasc = {0.}; constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component @@ -916,7 +899,7 @@ struct taggingHFE { covCasc[i] = cascade.positionCovMat()[i]; } - auto cascParCov = o2::track::TrackParCov(vertex, momentum, covCasc, cascade.sign(), true); + auto cascParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); cascParCov.setAbsCharge(1); if constexpr (cascType == 0) { cascParCov.setPID(o2::track::PID::XiMinus); @@ -995,8 +978,6 @@ struct taggingHFE { const auto& trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); electronIds.reserve(trackIdsThisCollision.size()); positronIds.reserve(trackIdsThisCollision.size()); - negKaonIds.reserve(trackIdsThisCollision.size()); - posKaonIds.reserve(trackIdsThisCollision.size()); for (const auto& trackId : trackIdsThisCollision) { const auto& track = trackId.template track_as(); @@ -1284,8 +1265,16 @@ struct taggingHFE { const auto& mcLambdac0 = mcParticles.rawIteratorAt(mcLambdacId); if (IsFromBeauty(mcLambdac0, mcParticles) < 0) { fRegistry.fill(HIST("MC/eLfromPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hLz"), eLpair.lz); } else { fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hLz"), eLpair.lz); } } } @@ -1340,8 +1329,16 @@ struct taggingHFE { const auto& mcLambdac0 = mcParticles.rawIteratorAt(mcLambdacId); if (IsFromBeauty(mcLambdac0, mcParticles) < 0) { fRegistry.fill(HIST("MC/eLfromPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hLz"), eLpair.lz); } else { fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hLz"), eLpair.lz); } } } @@ -1383,8 +1380,16 @@ struct taggingHFE { const auto& mcXic0 = mcParticles.rawIteratorAt(mcXic0Id); if (IsFromBeauty(mcXic0, mcParticles) < 0) { fRegistry.fill(HIST("MC/eXifromPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hLz"), eXipair.lz); } else { fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hLz"), eXipair.lz); } } } @@ -1445,8 +1450,16 @@ struct taggingHFE { const auto& mcXic0 = mcParticles.rawIteratorAt(mcXic0Id); if (IsFromBeauty(mcXic0, mcParticles) < 0) { fRegistry.fill(HIST("MC/eXifromPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromPromptXic0/hLz"), eXipair.lz); } else { fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hLz"), eXipair.lz); } } } @@ -1480,16 +1493,24 @@ struct taggingHFE { int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 2212, -211, 3122, mcParticles); if (mcLambdaId > 0) { // true Lambda const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); - int mcOmegaId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, 3122, -211, 3312, mcParticles); + int mcOmegaId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, 3122, -321, 3334, mcParticles); if (mcOmegaId > 0) { // true omegaMinus const auto& mcOmega = mcParticles.rawIteratorAt(mcOmegaId); - int mcOmegac0Id = FindCommonMotherFrom2Prongs(mcpos, mcOmega, -11, 3312, 4132, mcParticles); + int mcOmegac0Id = FindCommonMotherFrom2Prongs(mcpos, mcOmega, -11, 3334, 4332, mcParticles); if (mcOmegac0Id > 0) { // true Omegac0 const auto& mcOmegac0 = mcParticles.rawIteratorAt(mcOmegac0Id); if (IsFromBeauty(mcOmegac0, mcParticles) < 0) { fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hLz"), eOmegapair.lz); } else { fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hLz"), eOmegapair.lz); } } } @@ -1542,16 +1563,24 @@ struct taggingHFE { int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 211, -2212, -3122, mcParticles); if (mcLambdaId > 0) { // true AntiLambda const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); - int mcOmegaId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, -3122, 211, -3312, mcParticles); + int mcOmegaId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, -3122, 321, -3334, mcParticles); if (mcOmegaId > 0) { // true omegaPlus const auto& mcOmega = mcParticles.rawIteratorAt(mcOmegaId); - int mcOmegac0Id = FindCommonMotherFrom2Prongs(mcele, mcOmega, 11, -3312, 4132, mcParticles); + int mcOmegac0Id = FindCommonMotherFrom2Prongs(mcele, mcOmega, 11, -3334, 4332, mcParticles); if (mcOmegac0Id > 0) { // true Omegac0 const auto& mcOmegac0 = mcParticles.rawIteratorAt(mcOmegac0Id); if (IsFromBeauty(mcOmegac0, mcParticles) < 0) { fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hLz"), eOmegapair.lz); } else { fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hLz"), eOmegapair.lz); } } } @@ -1569,10 +1598,6 @@ struct taggingHFE { electronIds.shrink_to_fit(); positronIds.clear(); positronIds.shrink_to_fit(); - negKaonIds.clear(); - negKaonIds.shrink_to_fit(); - posKaonIds.clear(); - posKaonIds.shrink_to_fit(); lambdaIds.clear(); lambdaIds.shrink_to_fit(); @@ -1625,8 +1650,6 @@ struct taggingHFE { std::vector positronIdsLoose; std::vector electronIds; std::vector positronIds; - std::vector negKaonIds; - std::vector posKaonIds; std::vector lambdaIds; std::vector antilambdaIds; diff --git a/PWGEM/Dilepton/Utils/MlResponseO2Track.h b/PWGEM/Dilepton/Utils/MlResponseO2Track.h index ae0c17096fb..5e1f2fc4226 100644 --- a/PWGEM/Dilepton/Utils/MlResponseO2Track.h +++ b/PWGEM/Dilepton/Utils/MlResponseO2Track.h @@ -161,6 +161,7 @@ enum class InputFeaturesO2Track : uint8_t { tpctofNSigmaPr, tpcNClsFound, tpcNClsCrossedRows, + tpcChi2NCl, hasITS, hasTPC, hasTRD, @@ -215,6 +216,7 @@ class MlResponseO2Track : public MlResponse CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaPr, tpcNSigmaPr, tofNSigmaPr, hasTOF); CHECK_AND_FILL_O2_TRACK(tpcNClsFound); CHECK_AND_FILL_O2_TRACK(tpcNClsCrossedRows); + CHECK_AND_FILL_O2_TRACK(tpcChi2NCl); CHECK_AND_FILL_O2_TRACK(hasITS); CHECK_AND_FILL_O2_TRACK(hasTPC); CHECK_AND_FILL_O2_TRACK(hasTRD); @@ -295,6 +297,7 @@ class MlResponseO2Track : public MlResponse FILL_MAP_O2_TRACK(tpctofNSigmaPr), FILL_MAP_O2_TRACK(tpcNClsFound), FILL_MAP_O2_TRACK(tpcNClsCrossedRows), + FILL_MAP_O2_TRACK(tpcChi2NCl), FILL_MAP_O2_TRACK(hasITS), FILL_MAP_O2_TRACK(hasTPC), FILL_MAP_O2_TRACK(hasTRD), diff --git a/PWGEM/Dilepton/Utils/MomentumSmearer.h b/PWGEM/Dilepton/Utils/MomentumSmearer.h index 10699e4c2a0..d0e73ee971f 100644 --- a/PWGEM/Dilepton/Utils/MomentumSmearer.h +++ b/PWGEM/Dilepton/Utils/MomentumSmearer.h @@ -133,12 +133,15 @@ class MomentumSmearer } } - void fillVecReso(TH2F* fReso, std::vector& fVecReso) + void fillVecReso(TH2F* fReso, std::vector& fVecReso, const char* suffix) { - TAxis* axisPt = fReso->GetXaxis(); + TAxis* axisPt = fReso->GetXaxis(); // be careful! This works only for variable bin width. int nBinsPt = axisPt->GetNbins(); - for (int i = 1; i <= nBinsPt; i++) { - fVecReso.push_back(reinterpret_cast(fReso->ProjectionY("", i, i))); + fVecReso.resize(nBinsPt); + for (int i = 0; i < nBinsPt; i++) { + auto h1 = reinterpret_cast(fReso->ProjectionY(Form("h1reso%s_pt%d", suffix, i), i + 1, i + 1)); + h1->Scale(1.f, "width"); // convert ntrack to probability density + fVecReso[i] = h1; } } @@ -257,10 +260,10 @@ class MomentumSmearer if (!fResoPhi_Neg) { LOGP(fatal, "Could not open {} from file {}", fResPhiNegHistName.Data(), fResFileName.Data()); } - fillVecReso(fResoPt, fVecResoPt); - fillVecReso(fResoEta, fVecResoEta); - fillVecReso(fResoPhi_Pos, fVecResoPhi_Pos); - fillVecReso(fResoPhi_Neg, fVecResoPhi_Neg); + fillVecReso(fResoPt, fVecResoPt, "_reldpt"); + fillVecReso(fResoEta, fVecResoEta, "_deta"); + fillVecReso(fResoPhi_Pos, fVecResoPhi_Pos, "_dphi_pos"); + fillVecReso(fResoPhi_Neg, fVecResoPhi_Neg, "_dphi_neg"); } } @@ -361,7 +364,7 @@ class MomentumSmearer if (!fDCA) { LOGP(fatal, "Could not open {} from file {}", fDCAHistName.Data(), fDCAFileName.Data()); } - fillVecReso(fDCA, fVecDCA); + fillVecReso(fDCA, fVecDCA, "_dca"); } if (!fFromCcdb) { diff --git a/PWGEM/Dilepton/Utils/PairUtilities.h b/PWGEM/Dilepton/Utils/PairUtilities.h index 1fcede0e14d..6a574c3fb7e 100644 --- a/PWGEM/Dilepton/Utils/PairUtilities.h +++ b/PWGEM/Dilepton/Utils/PairUtilities.h @@ -42,8 +42,7 @@ enum class DileptonAnalysisType : int { kFlowV2 = 2, kFlowV3 = 3, kPolarization = 4, - kVM = 5, - kHFll = 6, + kHFll = 5, }; enum class DileptonHadronAnalysisType : int { diff --git a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx index 724b6347fa6..a4c42e37003 100644 --- a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx @@ -154,9 +154,6 @@ struct CreateEMEventPhoton { auto bc = collision.template foundBC_as(); initCCDB(bc); - if (!collision.isSelected()) { - continue; - } if (needEMCTrigger && !collision.alias_bit(kTVXinEMC)) { continue; } @@ -164,12 +161,18 @@ struct CreateEMEventPhoton { continue; } - if constexpr (eventtype == EMEventType::kEvent) { - event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); - } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { - event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), collision.centFT0C()); - } else { - event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); + if (collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + if constexpr (eventtype == EMEventType::kEvent) { + event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); + } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { + event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), collision.centFT0C()); + } else { + event_norm_info(collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), static_cast(10.f * collision.posZ()), 105.f); + } + } + + if (!collision.isSelected()) { + continue; } if (!collision.isEoI()) { // events with at least 1 photon for data reduction. diff --git a/PWGHF/Core/CentralityEstimation.h b/PWGHF/Core/CentralityEstimation.h index fbe18d28d89..916d183a289 100644 --- a/PWGHF/Core/CentralityEstimation.h +++ b/PWGHF/Core/CentralityEstimation.h @@ -107,7 +107,7 @@ float getCentralityColl(const TCollision& collision) template float getCentralityColl(const TCollision&) { - return 105.0f; + return -1.f; } /// Get the centrality @@ -146,7 +146,7 @@ float getCentralityColl(const TCollision& collision, const int centEstimator) LOG(fatal) << "Centrality estimator not valid. See CentralityEstimator for valid values."; break; } - return -999.f; + return -1.f; } /// \brief Function to get MC collision centrality @@ -155,11 +155,10 @@ float getCentralityColl(const TCollision& collision, const int centEstimator) template float getCentralityGenColl(TCollisions const& collSlice) { - using TMult = uint16_t; // type of numContrib + uint16_t multiplicity{}; // type of numContrib float centrality{-1.f}; - TMult multiplicity{}; for (const auto& collision : collSlice) { - const TMult collMult = collision.numContrib(); + const uint16_t collMult = collision.numContrib(); if (collMult > multiplicity) { centrality = getCentralityColl(collision); multiplicity = collMult; @@ -175,11 +174,10 @@ float getCentralityGenColl(TCollisions const& collSlice) template float getCentralityGenColl(TCollisions const& collSlice, const int centEstimator) { - using TMult = uint16_t; // type of numContrib + uint16_t multiplicity{}; // type of numContrib float centrality{-1.f}; - TMult multiplicity{}; for (const auto& collision : collSlice) { - const TMult collMult = collision.numContrib(); + const uint16_t collMult = collision.numContrib(); if (collMult > multiplicity) { centrality = getCentralityColl(collision, centEstimator); multiplicity = collMult; diff --git a/PWGHF/Core/HfMlResponseDstarToD0Pi.h b/PWGHF/Core/HfMlResponseDstarToD0Pi.h index af0351b2a73..f83c9114feb 100644 --- a/PWGHF/Core/HfMlResponseDstarToD0Pi.h +++ b/PWGHF/Core/HfMlResponseDstarToD0Pi.h @@ -61,26 +61,26 @@ // Very specific case of CHECK_AND_FILL_VEC_DSTAR_FULL(OBJECT, FEATURE, GETTER) // Use for push back different value for D*+ or D*- candidate -#define CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(POSGETTER, NEGGETTER, FEATURENAME) \ - case static_cast(InputFeaturesDstarToD0Pi::FEATURENAME): { \ - if (candidate.signSoftPi() > 0) { \ - inputFeatures.emplace_back(candidate.POSGETTER()); \ - } else { \ - inputFeatures.emplace_back(candidate.NEGGETTER()); \ - } \ - break; \ +#define CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(POSGETTER, NEGGETTER, FEATURENAME, SWAP) \ + case static_cast(InputFeaturesDstarToD0Pi::FEATURENAME): { \ + if (candidate.signSoftPi() > 0 || !SWAP) { \ + inputFeatures.emplace_back(candidate.POSGETTER()); \ + } else { \ + inputFeatures.emplace_back(candidate.NEGGETTER()); \ + } \ + break; \ } // Very specific case of CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(OBJECT, FEATURE, GETTER) // Use for push back different value for D*+ or D*- candidate getting the correct feature from two different objects (tracks) -#define CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(OBJECTPOS, OBJECTNEG, FEATURENAME, GETTER) \ - case static_cast(InputFeaturesDstarToD0Pi::FEATURENAME): { \ - if (candidate.signSoftPi() > 0) { \ - inputFeatures.emplace_back(OBJECTPOS.GETTER()); \ - } else { \ - inputFeatures.emplace_back(OBJECTNEG.GETTER()); \ - } \ - break; \ +#define CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(OBJECTPOS, OBJECTNEG, FEATURENAME, GETTER, SWAP) \ + case static_cast(InputFeaturesDstarToD0Pi::FEATURENAME): { \ + if (candidate.signSoftPi() > 0 || !SWAP) { \ + inputFeatures.emplace_back(OBJECTPOS.GETTER()); \ + } else { \ + inputFeatures.emplace_back(OBJECTNEG.GETTER()); \ + } \ + break; \ } // Very specific case of CHECK_AND_FILL_VEC_DSTAR_FULL(OBJECT, FEATURE, GETTER) @@ -164,7 +164,7 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse /// \param prongSoftPi is the candidate's prongSoftPi /// \return inputFeatures vector template - std::vector getInputFeatures(T1 const& candidate) + std::vector getInputFeatures(T1 const& candidate, bool swapDzeroDaus = true) { std::vector inputFeatures; @@ -179,36 +179,36 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse CHECK_AND_FILL_VEC_DSTAR(cpaXYD0); CHECK_AND_FILL_VEC_DSTAR(deltaIPNormalisedMaxD0); CHECK_AND_FILL_VEC_DSTAR(impactParameterProductD0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(ptProng0, ptProng1, ptProng0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(ptProng1, ptProng0, ptProng1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(ptProng0, ptProng1, ptProng0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(ptProng1, ptProng0, ptProng1, swapDzeroDaus); CHECK_AND_FILL_VEC_DSTAR(ptSoftPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameter0, impactParameter1, impactParameter0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameter1, impactParameter0, impactParameter1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZ0, impactParameterZ1, impactParameterZ0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZ1, impactParameterZ0, impactParameterZ1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameter0, impactParameter1, impactParameter0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameter1, impactParameter0, impactParameter1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZ0, impactParameterZ1, impactParameterZ0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZ1, impactParameterZ0, impactParameterZ1, swapDzeroDaus); CHECK_AND_FILL_VEC_DSTAR(impParamSoftPi); CHECK_AND_FILL_VEC_DSTAR(impParamZSoftPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterNormalised0, impactParameterNormalised1, impactParameterNormalised0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterNormalised1, impactParameterNormalised0, impactParameterNormalised1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZNormalised0, impactParameterZNormalised1, impactParameterZNormalised0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZNormalised1, impactParameterZNormalised0, impactParameterZNormalised1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterNormalised0, impactParameterNormalised1, impactParameterNormalised0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterNormalised1, impactParameterNormalised0, impactParameterNormalised1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZNormalised0, impactParameterZNormalised1, impactParameterZNormalised0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZNormalised1, impactParameterZNormalised0, impactParameterZNormalised1, swapDzeroDaus); CHECK_AND_FILL_VEC_DSTAR(normalisedImpParamSoftPi); CHECK_AND_FILL_VEC_DSTAR(normalisedImpParamZSoftPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(cosThetaStarD0, cosThetaStarD0Bar, cosThetaStarD0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(invMassD0, invMassD0Bar, massD0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(cosThetaStarD0, cosThetaStarD0Bar, cosThetaStarD0, true); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(invMassD0, invMassD0Bar, massD0, true); CHECK_AND_FILL_VEC_DSTAR_DELTA_MASS_D0(deltaMassD0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcPi0, nSigTpcPi1, nSigmaTPCPiPr0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcKa0, nSigTpcKa1, nSigmaTPCKaPr0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofPi0, nSigTofPi1, nSigmaTOFPiPr0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofKa0, nSigTofKa1, nSigmaTOFKaPr0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaPi0, tpcTofNSigmaPi1, nSigmaTPCTOFPiPr0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaKa0, tpcTofNSigmaKa1, nSigmaTPCTOFKaPr0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcPi1, nSigTpcPi0, nSigmaTPCPiPr1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcKa1, nSigTpcKa0, nSigmaTPCKaPr1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofPi1, nSigTofPi0, nSigmaTOFPiPr1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofKa1, nSigTofKa0, nSigmaTOFKaPr1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaPi1, tpcTofNSigmaPi0, nSigmaTPCTOFPiPr1); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaKa1, tpcTofNSigmaKa0, nSigmaTPCTOFKaPr1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcPi0, nSigTpcPi1, nSigmaTPCPiPr0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcKa0, nSigTpcKa1, nSigmaTPCKaPr0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofPi0, nSigTofPi1, nSigmaTOFPiPr0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofKa0, nSigTofKa1, nSigmaTOFKaPr0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaPi0, tpcTofNSigmaPi1, nSigmaTPCTOFPiPr0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaKa0, tpcTofNSigmaKa1, nSigmaTPCTOFKaPr0, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcPi1, nSigTpcPi0, nSigmaTPCPiPr1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcKa1, nSigTpcKa0, nSigmaTPCKaPr1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofPi1, nSigTofPi0, nSigmaTOFPiPr1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofKa1, nSigTofKa0, nSigmaTOFKaPr1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaPi1, tpcTofNSigmaPi0, nSigmaTPCTOFPiPr1, swapDzeroDaus); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaKa1, tpcTofNSigmaKa0, nSigmaTPCTOFKaPr1, swapDzeroDaus); CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTPCPiPrSoftPi, nSigTpcPi2); CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTPCKaPrSoftPi, nSigTpcKa2); CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTOFPiPrSoftPi, nSigTofPi2); @@ -221,28 +221,6 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse return inputFeatures; } - /// Method to get the input features used for D0 in HF triggers - /// \param candidate is the D* candidate - /// \return inputFeatures vector - template - std::vector getInputFeaturesTrigger(T1 const& candidate) - { - std::vector inputFeatures; - - for (const auto& idx : MlResponse::mCachedIndices) { - switch (idx) { - CHECK_AND_FILL_VEC_DSTAR(ptProng0); - CHECK_AND_FILL_VEC_DSTAR_GETTER(impactParameterXY0, impactParameter0); - CHECK_AND_FILL_VEC_DSTAR(impactParameterZ0); - CHECK_AND_FILL_VEC_DSTAR(ptProng1); - CHECK_AND_FILL_VEC_DSTAR_GETTER(impactParameterXY1, impactParameter1); - CHECK_AND_FILL_VEC_DSTAR(impactParameterZ1); - } - } - - return inputFeatures; - } - protected: /// Method to fill the map of available input features void setAvailableInputFeatures() diff --git a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx index f5f8734c652..4df706619fe 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx @@ -128,6 +128,13 @@ struct HfCandidateCreatorCharmResoReduced { ConfigurableAxis multPoolBins{"multPoolBins", {VARIABLE_WIDTH, 0., 45., 60., 75., 95, 250}, "event multiplicity pools (PV contributors for now)"}; ConfigurableAxis zPoolBins{"zPoolBins", {VARIABLE_WIDTH, -10.0, -4, -1, 1, 4, 10.0}, "z vertex position pools"}; } cfgMixedEvent; + struct : ConfigurableGroup { + std::string prefix = "trackRotation"; + Configurable enable{"enable", false, "enable rotation of track/V0 for background estimation"}; + Configurable numRotations{"numRotations", 12, "number of track/V0 rotations"}; + Configurable minRotAngleMultByPi{"minRotAngleMultByPi", 5. / 6, "Minimum angle rotation for track rotation, to be multiplied by pi"}; + Configurable maxRotAngleMultByPi{"maxRotAngleMultByPi", 7. / 6, "Maximum angle rotation for track rotation, to be multiplied by pi"}; + } cfgTrackRotation; // Histogram axes configurables struct : ConfigurableGroup { std::string prefix = "histAxes"; @@ -151,6 +158,7 @@ struct HfCandidateCreatorCharmResoReduced { HistogramRegistry registry{"registry"}; + float bkgRotationAngleStep{0.f}; void init(InitContext const&) { // histograms @@ -169,6 +177,7 @@ struct HfCandidateCreatorCharmResoReduced { for (int iBin = 0; iBin < kNBinsSelections; ++iBin) { registry.get(HIST("hSelections"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } + bkgRotationAngleStep = (cfgTrackRotation.numRotations > 1) ? (cfgTrackRotation.maxRotAngleMultByPi - cfgTrackRotation.minRotAngleMultByPi) * constants::math::PI / (cfgTrackRotation.numRotations - 1) : 0.; } bool isInMassInterval(float invMass, int ptBin) @@ -341,210 +350,46 @@ struct HfCandidateCreatorCharmResoReduced { { std::vector> pVectorCharmProngs = {candD.pVectorProng0(), candD.pVectorProng1()}; std::array pVecD = candD.pVector(); - std::array pVecV0Tr = candV0Tr.pVector(); - float invMassReso{-1}, invMassV0Tr{-1}, invMassD{-1}; - int8_t signReso{0}, isWrongSign{0}; - double ptReso = RecoDecay::pt(RecoDecay::sumOfVec(pVecV0Tr, pVecD)); - if constexpr (dType == DType::Dplus) { - invMassD = candD.invMassDplus(); - pVectorCharmProngs.push_back(candD.pVectorProng2()); - if constexpr (bachType == BachelorType::V0) { - if (cfgV0Cuts.v0Type == V0Type::K0s) { // K0s - invMassV0Tr = candV0Tr.invMassK0s(); - signReso = candD.sign(); - if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0Short}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassK0Short}); - } - } else if (cfgV0Cuts.v0Type == V0Type::Lambda) { // Lambda - if (candV0Tr.v0Type() == V0Type::Lambda) { - invMassV0Tr = candV0Tr.invMassLambda(); - signReso = candD.sign(); - } else if (candV0Tr.v0Type() == V0Type::AntiLambda) { - invMassV0Tr = candV0Tr.invMassAntiLambda(); - signReso = candD.sign(); - isWrongSign = 1; - } - if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassLambda}); - } - } - rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], - pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], - invMassReso, - invMassD, - invMassV0Tr, - signReso, - isWrongSign); - rowCandidateResoIndices3PrV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); - registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); - registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); - registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); - } else if constexpr (bachType == BachelorType::Track) { - signReso = candD.sign() + candV0Tr.sign(); - isWrongSign = candD.sign() * candV0Tr.sign() > 0 ? 1 : 0; - if (cfgTrackCuts.massHypo == TrackType::Pion) { // Pion - invMassV0Tr = MassPiPlus; - if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassPiPlus}); - } - } else if (cfgTrackCuts.massHypo == TrackType::Kaon) { // Kaon - invMassV0Tr = MassKPlus; - if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassKPlus}); - } - } else if (cfgTrackCuts.massHypo == TrackType::Proton) { // Proton - invMassV0Tr = MassProton; - if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassProton}); - } - } - rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], - pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], - invMassReso, - invMassD, - invMassV0Tr, - signReso, - isWrongSign); - rowCandidateResoIndices3PrTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); - registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); - registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); - registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); - } - } else if constexpr (dType == DType::Dstar) { - float invMassD0; - if (candD.sign() > 0) { - invMassD = candD.invMassDstar(); - invMassD0 = candD.invMassD0(); - } else { - invMassD = candD.invMassAntiDstar(); - invMassD0 = candD.invMassD0Bar(); - } - pVectorCharmProngs.push_back(candD.pVectorProng2()); - if constexpr (bachType == BachelorType::V0) { - signReso = candD.sign(); - if (cfgV0Cuts.v0Type == V0Type::K0s) { // K0s - invMassV0Tr = candV0Tr.invMassK0s(); - if (useDeltaMass) { - if (candD.sign() > 0) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0Short}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0Short}) - invMassD; - } - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassK0Short}); - } - } else if (cfgV0Cuts.v0Type == V0Type::Lambda) { // Lambda - if (candV0Tr.v0Type() == V0Type::Lambda) { - invMassV0Tr = candV0Tr.invMassLambda(); - } else if (candV0Tr.v0Type() == V0Type::AntiLambda) { - invMassV0Tr = candV0Tr.invMassAntiLambda(); - isWrongSign = 1; - } - if (useDeltaMass) { - if (candD.sign() > 0) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}) - invMassD; - } - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassLambda}); - } - } - rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], - pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], - invMassReso, - invMassD - invMassD0, - invMassV0Tr, - signReso, - isWrongSign); - rowCandidateResoIndicesDstarV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); - registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); - registry.fill(HIST("hMassDmesDauVsPt"), invMassD - invMassD0, candD.pt()); - registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); - } else if constexpr (bachType == BachelorType::Track) { - signReso = candD.sign() + candV0Tr.sign(); - isWrongSign = candD.sign() * candV0Tr.sign() > 0 ? 1 : 0; - if (cfgTrackCuts.massHypo == TrackType::Pion) { // Pion - invMassV0Tr = MassPiPlus; - if (useDeltaMass) { - if (candD.sign() > 0) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; - } - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassPiPlus}); - } - } else if (cfgTrackCuts.massHypo == TrackType::Kaon) { // Kaon - invMassV0Tr = MassKPlus; - if (useDeltaMass) { - if (candD.sign() > 0) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}) - invMassD; - } - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassKPlus}); - } - } else if (cfgTrackCuts.massHypo == TrackType::Proton) { // Proton - invMassV0Tr = MassProton; - if (useDeltaMass) { - if (candD.sign() > 0) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}) - invMassD; - } else { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}) - invMassD; - } - } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassProton}); - } - } - rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], - pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], - invMassReso, - invMassD - invMassD0, - invMassV0Tr, - signReso, - isWrongSign); - rowCandidateResoIndicesDstarTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); - registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); - registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); - registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); + int numFills = (cfgTrackRotation.enable) ? cfgTrackRotation.numRotations : 1; // number of times we fil the tables: default 1, but more in case of track rotation + + for (int iFill{0}; iFill < numFills; ++iFill) { + + std::array pVecV0Tr = candV0Tr.pVector(); + if (cfgTrackRotation.enable) { // let's rotate + float bkgRotAngle = cfgTrackRotation.minRotAngleMultByPi * constants::math::PI + bkgRotationAngleStep * iFill; + pVecV0Tr = std::array{candV0Tr.px() * std::cos(bkgRotAngle) - candV0Tr.py() * std::sin(bkgRotAngle), candV0Tr.px() * std::sin(bkgRotAngle) + candV0Tr.py() * std::cos(bkgRotAngle), candV0Tr.pz()}; } - } else if constexpr (dType == DType::D0) { - // D0 - if (TESTBIT(selectionFlag, D0Sel::selectedD0)) { - invMassD = candD.invMassD0(); + + float invMassReso{-1}, invMassV0Tr{-1}, invMassD{-1}; + int8_t signReso{0}, isWrongSign{0}; + double ptReso = RecoDecay::pt(RecoDecay::sumOfVec(pVecV0Tr, pVecD)); + + if constexpr (dType == DType::Dplus) { + invMassD = candD.invMassDplus(); + pVectorCharmProngs.push_back(candD.pVectorProng2()); if constexpr (bachType == BachelorType::V0) { - signReso = 0; if (cfgV0Cuts.v0Type == V0Type::K0s) { // K0s invMassV0Tr = candV0Tr.invMassK0s(); + signReso = candD.sign(); if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassK0Short}) - invMassD; + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0Short}) - invMassD; } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassK0Short}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassK0Short}); } } else if (cfgV0Cuts.v0Type == V0Type::Lambda) { // Lambda if (candV0Tr.v0Type() == V0Type::Lambda) { invMassV0Tr = candV0Tr.invMassLambda(); + signReso = candD.sign(); } else if (candV0Tr.v0Type() == V0Type::AntiLambda) { invMassV0Tr = candV0Tr.invMassAntiLambda(); + signReso = candD.sign(); isWrongSign = 1; } if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassLambda}) - invMassD; + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}) - invMassD; } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassLambda}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassLambda}); } } rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], @@ -554,33 +399,33 @@ struct HfCandidateCreatorCharmResoReduced { invMassV0Tr, signReso, isWrongSign); - rowCandidateResoIndices2PrV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + rowCandidateResoIndices3PrV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); } else if constexpr (bachType == BachelorType::Track) { - signReso = candV0Tr.sign(); - isWrongSign = candV0Tr.sign() > 0 ? 0 : 1; + signReso = candD.sign() + candV0Tr.sign(); + isWrongSign = candD.sign() * candV0Tr.sign() > 0 ? 1 : 0; if (cfgTrackCuts.massHypo == TrackType::Pion) { // Pion invMassV0Tr = MassPiPlus; if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus}) - invMassD; + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassPiPlus}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassPiPlus}); } } else if (cfgTrackCuts.massHypo == TrackType::Kaon) { // Kaon invMassV0Tr = MassKPlus; if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassKPlus}) - invMassD; + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}) - invMassD; } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassKPlus}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassKPlus}); } } else if (cfgTrackCuts.massHypo == TrackType::Proton) { // Proton invMassV0Tr = MassProton; if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassProton}) - invMassD; + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}) - invMassD; } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassProton}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDPlus, MassProton}); } } rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], @@ -590,85 +435,260 @@ struct HfCandidateCreatorCharmResoReduced { invMassV0Tr, signReso, isWrongSign); - rowCandidateResoIndices2PrTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + rowCandidateResoIndices3PrTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); } - } - // D0bar - if (TESTBIT(selectionFlag, D0Sel::selectedD0Bar)) { - invMassD = candD.invMassD0Bar(); + } else if constexpr (dType == DType::Dstar) { + float invMassD0; + if (candD.sign() > 0) { + invMassD = candD.invMassDstar(); + invMassD0 = candD.invMassD0(); + } else { + invMassD = candD.invMassAntiDstar(); + invMassD0 = candD.invMassD0Bar(); + } + pVectorCharmProngs.push_back(candD.pVectorProng2()); if constexpr (bachType == BachelorType::V0) { - signReso = 0; + signReso = candD.sign(); if (cfgV0Cuts.v0Type == V0Type::K0s) { // K0s invMassV0Tr = candV0Tr.invMassK0s(); if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassK0Short}) - invMassD; + if (candD.sign() > 0) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0Short}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0Short}) - invMassD; + } } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassK0Short}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassK0Short}); } } else if (cfgV0Cuts.v0Type == V0Type::Lambda) { // Lambda if (candV0Tr.v0Type() == V0Type::Lambda) { invMassV0Tr = candV0Tr.invMassLambda(); - isWrongSign = 1; } else if (candV0Tr.v0Type() == V0Type::AntiLambda) { invMassV0Tr = candV0Tr.invMassAntiLambda(); + isWrongSign = 1; } if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassLambda}) - invMassD; + if (candD.sign() > 0) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}) - invMassD; + } } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassLambda}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassLambda}); } } rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], invMassReso, - invMassD, + invMassD - invMassD0, invMassV0Tr, signReso, isWrongSign); - rowCandidateResoIndices2PrV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + rowCandidateResoIndicesDstarV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); - registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); + registry.fill(HIST("hMassDmesDauVsPt"), invMassD - invMassD0, candD.pt()); registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); } else if constexpr (bachType == BachelorType::Track) { - signReso = candV0Tr.sign(); - isWrongSign = candV0Tr.sign() > 0 ? 1 : 0; + signReso = candD.sign() + candV0Tr.sign(); + isWrongSign = candD.sign() * candV0Tr.sign() > 0 ? 1 : 0; if (cfgTrackCuts.massHypo == TrackType::Pion) { // Pion invMassV0Tr = MassPiPlus; if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; + if (candD.sign() > 0) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; + } } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassPiPlus}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassPiPlus}); } } else if (cfgTrackCuts.massHypo == TrackType::Kaon) { // Kaon invMassV0Tr = MassKPlus; if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassKPlus}) - invMassD; + if (candD.sign() > 0) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}) - invMassD; + } } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassKPlus}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassKPlus}); } } else if (cfgTrackCuts.massHypo == TrackType::Proton) { // Proton invMassV0Tr = MassProton; if (useDeltaMass) { - invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassProton}) - invMassD; + if (candD.sign() > 0) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[1], pVectorCharmProngs[0], pVectorCharmProngs[2], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}) - invMassD; + } } else { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassProton}); + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassDStar, MassProton}); } } rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], invMassReso, - invMassD, + invMassD - invMassD0, invMassV0Tr, signReso, isWrongSign); - rowCandidateResoIndices2PrTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + rowCandidateResoIndicesDstarTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); } + } else if constexpr (dType == DType::D0) { + // D0 + if (TESTBIT(selectionFlag, D0Sel::selectedD0)) { + invMassD = candD.invMassD0(); + if constexpr (bachType == BachelorType::V0) { + signReso = 0; + if (cfgV0Cuts.v0Type == V0Type::K0s) { // K0s + invMassV0Tr = candV0Tr.invMassK0s(); + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassK0Short}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassK0Short}); + } + } else if (cfgV0Cuts.v0Type == V0Type::Lambda) { // Lambda + if (candV0Tr.v0Type() == V0Type::Lambda) { + invMassV0Tr = candV0Tr.invMassLambda(); + } else if (candV0Tr.v0Type() == V0Type::AntiLambda) { + invMassV0Tr = candV0Tr.invMassAntiLambda(); + isWrongSign = 1; + } + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassLambda}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassLambda}); + } + } + rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], + pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], + invMassReso, + invMassD, + invMassV0Tr, + signReso, + isWrongSign); + rowCandidateResoIndices2PrV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); + registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); + registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); + } else if constexpr (bachType == BachelorType::Track) { + signReso = candV0Tr.sign(); + isWrongSign = candV0Tr.sign() > 0 ? 0 : 1; + if (cfgTrackCuts.massHypo == TrackType::Pion) { // Pion + invMassV0Tr = MassPiPlus; + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassPiPlus}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassPiPlus}); + } + } else if (cfgTrackCuts.massHypo == TrackType::Kaon) { // Kaon + invMassV0Tr = MassKPlus; + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassKPlus}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassKPlus}); + } + } else if (cfgTrackCuts.massHypo == TrackType::Proton) { // Proton + invMassV0Tr = MassProton; + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassPiPlus, MassKPlus, MassProton}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0, MassProton}); + } + } + rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], + pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], + invMassReso, + invMassD, + invMassV0Tr, + signReso, + isWrongSign); + rowCandidateResoIndices2PrTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); + registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); + registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); + } + } + // D0bar + if (TESTBIT(selectionFlag, D0Sel::selectedD0Bar)) { + invMassD = candD.invMassD0Bar(); + if constexpr (bachType == BachelorType::V0) { + signReso = 0; + if (cfgV0Cuts.v0Type == V0Type::K0s) { // K0s + invMassV0Tr = candV0Tr.invMassK0s(); + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassK0Short}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassK0Short}); + } + } else if (cfgV0Cuts.v0Type == V0Type::Lambda) { // Lambda + if (candV0Tr.v0Type() == V0Type::Lambda) { + invMassV0Tr = candV0Tr.invMassLambda(); + isWrongSign = 1; + } else if (candV0Tr.v0Type() == V0Type::AntiLambda) { + invMassV0Tr = candV0Tr.invMassAntiLambda(); + } + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassLambda}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassLambda}); + } + } + rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], + pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], + invMassReso, + invMassD, + invMassV0Tr, + signReso, + isWrongSign); + rowCandidateResoIndices2PrV0s(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); + registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); + registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); + } else if constexpr (bachType == BachelorType::Track) { + signReso = candV0Tr.sign(); + isWrongSign = candV0Tr.sign() > 0 ? 1 : 0; + if (cfgTrackCuts.massHypo == TrackType::Pion) { // Pion + invMassV0Tr = MassPiPlus; + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassPiPlus}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassPiPlus}); + } + } else if (cfgTrackCuts.massHypo == TrackType::Kaon) { // Kaon + invMassV0Tr = MassKPlus; + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassKPlus}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassKPlus}); + } + } else if (cfgTrackCuts.massHypo == TrackType::Proton) { // Proton + invMassV0Tr = MassProton; + if (useDeltaMass) { + invMassReso = RecoDecay::m(std::array{pVectorCharmProngs[0], pVectorCharmProngs[1], pVecV0Tr}, std::array{MassKPlus, MassPiPlus, MassProton}) - invMassD; + } else { + invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{MassD0Bar, MassProton}); + } + } + rowCandidateReso(pVecD[0], pVecD[1], pVecD[2], + pVecV0Tr[0], pVecV0Tr[1], pVecV0Tr[2], + invMassReso, + invMassD, + invMassV0Tr, + signReso, + isWrongSign); + rowCandidateResoIndices2PrTrks(collision.globalIndex(), candD.globalIndex(), candV0Tr.globalIndex()); + registry.fill(HIST("hMassResoVsPt"), invMassReso, ptReso); + registry.fill(HIST("hMassDmesDauVsPt"), invMassD, candD.pt()); + registry.fill(HIST("hMassV0DauVsPt"), invMassV0Tr, candV0Tr.pt()); + } + } } } } diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index 8b38982c477..9734cf40148 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -1241,7 +1241,7 @@ struct HfDataCreatorCharmHadPiReduced { trackParCov1.propagateTo(secondaryVertexCharm[0], bz); df2.getTrack(0).getPxPyPzGlo(pVec0); df2.getTrack(1).getPxPyPzGlo(pVec1); - pVecCharm = RecoDecay::pVec(pVec0, pVec1); + pVecCharm = RecoDecay::pVec(pVec0, pVec1, pVec2); trackParCovCharmHad = df2.createParentTrackParCov(); trackParCovCharmHad.setAbsCharge(0); // to be sure } @@ -1279,7 +1279,7 @@ struct HfDataCreatorCharmHadPiReduced { } // reject pi D with same sign as D - if constexpr (decChannel == DecayChannel::B0ToDminusPi || decChannel == DecayChannel::BsToDsminusPi || decChannel == DecayChannel::LbToLcplusPi || decChannel == DecayChannel::B0ToDstarPi) { // D∓ → π∓ K± π∓ and Ds∓ → K∓ K± π∓ and Lc∓ → p∓ K± π∓ and D*+ → D0 π+ + if constexpr (decChannel == DecayChannel::B0ToDminusPi || decChannel == DecayChannel::BsToDsminusPi || decChannel == DecayChannel::LbToLcplusPi) { // D∓ → π∓ K± π∓ and Ds∓ → K∓ K± π∓ and Lc∓ → p∓ K± π∓ if (trackPion.sign() * charmHadDauTracks[0].sign() > 0) { continue; } @@ -1287,6 +1287,10 @@ struct HfDataCreatorCharmHadPiReduced { if (!((candC.isSelD0() >= hfflagConfigurations.selectionFlagD0 && trackPion.sign() < 0) || (candC.isSelD0bar() >= hfflagConfigurations.selectionFlagD0bar && trackPion.sign() > 0))) { continue; } + } else if constexpr (decChannel == DecayChannel::B0ToDstarPi) { // D*+ → D0 π+ + if (trackPion.sign() * charmHadDauTracks.back().sign() > 0) { + continue; + } } // apply selections on pion tracks diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index 169e4fcd834..fefbd739f11 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -101,7 +101,7 @@ DECLARE_SOA_COLUMN(FlagWrongCollision, flagWrongCollision, int8_t); } // namespace hf_cand_b0_lite DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with some B0 properties - // B meson features hf_cand_b0_lite::M, + // B meson features hf_cand_b0_lite::M, hf_cand_b0_lite::Pt, hf_cand_b0_lite::Eta, @@ -616,7 +616,7 @@ struct HfTaskB0Reduced { candidate.decayLengthXY(), candidate.decayLengthNormalised(), candidate.decayLengthXYNormalised(), - candidate.impactParameterProngSqSum(), + candidate.impactParameterProduct(), candidate.maxNormalisedDeltaIP(), candidateMlScoreSig, candidate.isSelB0ToDPi(), @@ -644,12 +644,12 @@ struct HfTaskB0Reduced { prong0MlScorePrompt, prong0MlScoreNonprompt, // pion features - candidate.ptProng1(), + candidate.ptProng2(), std::abs(RecoDecay::eta(prongBachPi.pVector())), prongBachPi.itsNCls(), prongBachPi.tpcNClsCrossedRows(), prongBachPi.tpcChi2NCl(), - candidate.impactParameter1(), + candidate.impactParameter2(), prongBachPi.tpcNSigmaPi(), prongBachPi.tofNSigmaPi(), prongBachPi.tpcTofNSigmaPi(), diff --git a/PWGHF/D2H/Tasks/taskBsReduced.cxx b/PWGHF/D2H/Tasks/taskBsReduced.cxx index a5a89e241cf..098814b8e37 100644 --- a/PWGHF/D2H/Tasks/taskBsReduced.cxx +++ b/PWGHF/D2H/Tasks/taskBsReduced.cxx @@ -50,58 +50,111 @@ namespace o2::aod { namespace hf_cand_bs_lite { -DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong0 (GeV/c) -DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong1 (GeV/c) -DECLARE_SOA_COLUMN(MProng0, mProng0, float); //! Invariant mass of prong0 (GeV/c) +// B meson features DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate -DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) -DECLARE_SOA_COLUMN(NSigTpcPi1, nSigTpcPi1, float); //! TPC Nsigma separation for prong1 with pion mass hypothesis -DECLARE_SOA_COLUMN(NSigTofPi1, nSigTofPi1, float); //! TOF Nsigma separation for prong1 with pion mass hypothesis +DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate +DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length of candidate (cm) DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! Normalised transverse decay length of candidate DECLARE_SOA_COLUMN(ImpactParameterProduct, impactParameterProduct, float); //! Impact parameter product of candidate -DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate -DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! Maximum normalized difference between measured and expected impact parameter of candidate prongs DECLARE_SOA_COLUMN(MlScoreSig, mlScoreSig, float); //! ML score for signal class +// D meson features +DECLARE_SOA_COLUMN(MProng0, mProng0, float); //! Invariant mass of prong0 (GeV/c) +DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong0 (GeV/c) +DECLARE_SOA_COLUMN(DecayLength0, decayLength0, float); //! Decay length of D-meson daughter candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthXY0, decayLengthXY0, float); //! Transverse decay length of D-meson daughter candidate (cm) +DECLARE_SOA_COLUMN(ImpactParameter0, impactParameter0, float); //! Impact parameter product of D-meson daughter candidate +DECLARE_SOA_COLUMN(PtDmesProngMin, ptDmesProngMin, float); //! Minimum pT of prongs of D-meson daughter candidate (GeV/c) +DECLARE_SOA_COLUMN(AbsEtaDmesProngMin, absEtaDmesProngMin, float); //! Minimum absolute pseudorapidity of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(ItsNClsDmesProngMin, itsNClsDmesProngMin, int); //! Minimum number of ITS clusters of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsDmesProngMin, tpcNClsCrossedRowsDmesProngMin, int); //! Minimum number of TPC crossed rows of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(TpcChi2NClDmesProngMax, tpcChi2NClDmesProngMax, float); //! Maximum TPC chi2 of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(NSigTpcPiDmesProng0, nSigTpcPiDmesProng0, float); //! TPC Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiDmesProng0, nSigTofPiDmesProng0, float); //! TOF Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiDmesProng0, nSigTpcTofPiDmesProng0, float); //! Combined TPC and TOF Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcKaDmesProng1, nSigTpcKaDmesProng1, float); //! TPC Nsigma separation for D-meson prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofKaDmesProng1, nSigTofKaDmesProng1, float); //! TOF Nsigma separation for D-meson prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofKaDmesProng1, nSigTpcTofKaDmesProng1, float); //! Combined TPC and TOF Nsigma separation for D-meson prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcPiDmesProng2, nSigTpcPiDmesProng2, float); //! TPC Nsigma separation for D-meson prong2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiDmesProng2, nSigTofPiDmesProng2, float); //! TOF Nsigma separation for D-meson prong2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiDmesProng2, nSigTpcTofPiDmesProng2, float); //! Combined TPC and TOF Nsigma separation for D-meson prong0 with pion mass hypothesis +// pion features +DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong1 (GeV/c) +DECLARE_SOA_COLUMN(AbsEtaProng1, absEtaProng1, float); //! Absolute pseudorapidity of Prong1 +DECLARE_SOA_COLUMN(ItsNClsProng1, itsNClsProng1, int); //! Number of ITS clusters of Prong1 +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsProng1, tpcNClsCrossedRowsProng1, int); //! Number of TPC crossed rows of prongs of Prong1 +DECLARE_SOA_COLUMN(TpcChi2NClProng1, tpcChi2NClProng1, float); //! Maximum TPC chi2 of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(ImpactParameterProng1, impactParameterProng1, float); //! Impact parameter product of bachelor pion +DECLARE_SOA_COLUMN(NSigTpcPiProng1, nSigTpcPiProng1, float); //! TPC Nsigma separation for prong1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiProng1, nSigTofPiProng1, float); //! TOF Nsigma separation for prong1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiProng1, nSigTpcTofPiProng1, float); //! Combined TPC and TOF Nsigma separation for prong1 with pion mass hypothesis +// MC truth DECLARE_SOA_COLUMN(FlagWrongCollision, flagWrongCollision, int8_t); //! Flag for association with wrong collision +DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! Transverse momentum of candidate (GeV/c) +// General vars (unused for now) +DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) } // namespace hf_cand_bs_lite DECLARE_SOA_TABLE(HfRedCandBsLites, "AOD", "HFREDCANDBSLITE", //! Table with some Bs properties + // B meson features + hf_cand_bs_lite::M, + hf_cand_bs_lite::Pt, + hf_cand_bs_lite::Eta, + hf_cand_bs_lite::Phi, + hf_cand_bs_lite::Y, + hf_cand_bs_lite::Cpa, + hf_cand_bs_lite::CpaXY, hf_cand::Chi2PCA, hf_cand_bs_lite::DecayLength, hf_cand_bs_lite::DecayLengthXY, hf_cand_bs_lite::DecayLengthNormalised, hf_cand_bs_lite::DecayLengthXYNormalised, + hf_cand_bs_lite::ImpactParameterProduct, + hf_cand_bs_lite::MaxNormalisedDeltaIP, + hf_cand_bs_lite::MlScoreSig, + hf_sel_candidate_bs::IsSelBsToDsPi, + // D meson features hf_cand_bs_lite::MProng0, hf_cand_bs_lite::PtProng0, - hf_cand_bs_lite::PtProng1, - hf_cand::ImpactParameter0, - hf_cand::ImpactParameter1, - hf_cand_bs_lite::ImpactParameterProduct, - hf_cand_bs_lite::NSigTpcPi1, - hf_cand_bs_lite::NSigTofPi1, + hf_cand_bs_lite::DecayLength0, + hf_cand_bs_lite::DecayLengthXY0, + hf_cand_bs_lite::ImpactParameter0, + hf_cand_bs_lite::PtDmesProngMin, + hf_cand_bs_lite::AbsEtaDmesProngMin, + hf_cand_bs_lite::ItsNClsDmesProngMin, + hf_cand_bs_lite::TpcNClsCrossedRowsDmesProngMin, + hf_cand_bs_lite::TpcChi2NClDmesProngMax, + hf_cand_bs_lite::NSigTpcPiDmesProng0, + hf_cand_bs_lite::NSigTofPiDmesProng0, + hf_cand_bs_lite::NSigTpcTofPiDmesProng0, + hf_cand_bs_lite::NSigTpcKaDmesProng1, + hf_cand_bs_lite::NSigTofKaDmesProng1, + hf_cand_bs_lite::NSigTpcTofKaDmesProng1, + hf_cand_bs_lite::NSigTpcPiDmesProng2, + hf_cand_bs_lite::NSigTofPiDmesProng2, + hf_cand_bs_lite::NSigTpcTofPiDmesProng2, hf_cand_bs_reduced::Prong0MlScoreBkg, hf_cand_bs_reduced::Prong0MlScorePrompt, hf_cand_bs_reduced::Prong0MlScoreNonprompt, - hf_cand_bs_lite::MlScoreSig, - hf_sel_candidate_bs::IsSelBsToDsPi, - hf_cand_bs_lite::M, - hf_cand_bs_lite::Pt, - hf_cand_bs_lite::Cpa, - hf_cand_bs_lite::CpaXY, - hf_cand_bs_lite::MaxNormalisedDeltaIP, - hf_cand_bs_lite::Eta, - hf_cand_bs_lite::Phi, - hf_cand_bs_lite::Y, + // pion features + hf_cand_bs_lite::PtProng1, + hf_cand_bs_lite::AbsEtaProng1, + hf_cand_bs_lite::ItsNClsProng1, + hf_cand_bs_lite::TpcNClsCrossedRowsProng1, + hf_cand_bs_lite::TpcChi2NClProng1, + hf_cand_bs_lite::ImpactParameterProng1, + hf_cand_bs_lite::NSigTpcPiProng1, + hf_cand_bs_lite::NSigTofPiProng1, + hf_cand_bs_lite::NSigTpcTofPiProng1, + // MC truth hf_cand_3prong::FlagMcMatchRec, hf_cand_3prong::OriginMcRec, hf_cand_bs_lite::FlagWrongCollision, @@ -143,6 +196,7 @@ struct HfTaskBsReduced { HfHelper hfHelper; using TracksPion = soa::Join; + using CandsDS = soa::Join; Filter filterSelectCandidates = (aod::hf_sel_candidate_bs::isSelBsToDsPi >= selectionFlagBs); @@ -344,13 +398,13 @@ struct HfTaskBsReduced { /// \param withBsMl is the flag to enable the filling with ML scores for the Bs candidate /// \param candidate is the Bs candidate /// \param candidatesD is the table with Ds- candidates - template + template void fillCand(Cand const& candidate, - aod::HfRed3Prongs const&) + CandsDmes const&) { auto ptCandBs = candidate.pt(); auto invMassBs = hfHelper.invMassBsToDsPi(candidate); - auto candDs = candidate.template prong0_as(); + auto candDs = candidate.template prong0_as(); auto ptDs = candidate.ptProng0(); auto invMassDs = candDs.invMassHypo0() > 0 ? candDs.invMassHypo0() : candDs.invMassHypo1(); // TODO: here we are assuming that only one of the two hypotheses is filled, to be checked @@ -513,32 +567,57 @@ struct HfTaskBsReduced { } hfRedCandBsLite( + // B meson features + invMassBs, + ptCandBs, + candidate.eta(), + candidate.phi(), + hfHelper.yBs(candidate), + candidate.cpa(), + candidate.cpaXY(), candidate.chi2PCA(), candidate.decayLength(), candidate.decayLengthXY(), candidate.decayLengthNormalised(), candidate.decayLengthXYNormalised(), + candidate.impactParameterProduct(), + candidate.maxNormalisedDeltaIP(), + candidateMlScoreSig, + candidate.isSelBsToDsPi(), + // D meson features invMassDs, ptDs, - candidate.ptProng1(), + decLenDs, + decLenXyDs, candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameterProduct(), - prong1.tpcNSigmaPi(), - prong1.tofNSigmaPi(), + candDs.ptProngMin(), + candDs.absEtaProngMin(), + candDs.itsNClsProngMin(), + candDs.tpcNClsCrossedRowsProngMin(), + candDs.tpcChi2NClProngMax(), + candDs.tpcNSigmaPiProng0(), + candDs.tofNSigmaPiProng0(), + candDs.tpcTofNSigmaPiProng0(), + candDs.tpcNSigmaKaProng1(), + candDs.tofNSigmaKaProng1(), + candDs.tpcTofNSigmaKaProng1(), + candDs.tpcNSigmaKaProng2(), + candDs.tofNSigmaKaProng2(), + candDs.tpcTofNSigmaKaProng2(), prong0MlScoreBkg, prong0MlScorePrompt, prong0MlScoreNonprompt, - candidateMlScoreSig, - candidate.isSelBsToDsPi(), - invMassBs, - ptCandBs, - candidate.cpa(), - candidate.cpaXY(), - candidate.maxNormalisedDeltaIP(), - candidate.eta(), - candidate.phi(), - hfHelper.yBs(candidate), + // pion features + candidate.ptProng1(), + std::abs(RecoDecay::eta(prong1.pVector())), + prong1.itsNCls(), + prong1.tpcNClsCrossedRows(), + prong1.tpcChi2NCl(), + candidate.impactParameter1(), + prong1.tpcNSigmaPi(), + prong1.tofNSigmaPi(), + prong1.tpcTofNSigmaPi(), + // MC truth flagMcMatchRec, isSignal, flagWrongCollision, @@ -612,7 +691,7 @@ struct HfTaskBsReduced { // Process functions void processData(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { for (const auto& candidate : candidates) { @@ -625,7 +704,7 @@ struct HfTaskBsReduced { PROCESS_SWITCH(HfTaskBsReduced, processData, "Process data without ML scores for Bs and D daughter", true); void processDataWithDmesMl(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { for (const auto& candidate : candidates) { @@ -638,7 +717,7 @@ struct HfTaskBsReduced { PROCESS_SWITCH(HfTaskBsReduced, processDataWithDmesMl, "Process data with(out) ML scores for D daughter (Bs)", false); void processDataWithBsMl(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { for (const auto& candidate : candidates) { @@ -652,7 +731,7 @@ struct HfTaskBsReduced { void processMc(soa::Filtered> const& candidates, aod::HfMcGenRedBss const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { // MC rec @@ -672,7 +751,7 @@ struct HfTaskBsReduced { void processMcWithDecayTypeCheck(soa::Filtered> const& candidates, aod::HfMcGenRedBss const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { // MC rec @@ -692,7 +771,7 @@ struct HfTaskBsReduced { void processMcWithDmesMl(soa::Filtered> const& candidates, aod::HfMcGenRedBss const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { // MC rec @@ -712,7 +791,7 @@ struct HfTaskBsReduced { void processMcWithDmesMlAndDecayTypeCheck(soa::Filtered> const& candidates, aod::HfMcGenRedBss const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { // MC rec @@ -732,7 +811,7 @@ struct HfTaskBsReduced { void processMcWithBsMl(soa::Filtered> const& candidates, aod::HfMcGenRedBss const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { // MC rec @@ -752,7 +831,7 @@ struct HfTaskBsReduced { void processMcWithBsMlAndDecayTypeCheck(soa::Filtered> const& candidates, aod::HfMcGenRedBss const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDS const& candidatesD, TracksPion const&) { // MC rec diff --git a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx index 16da492051f..f938e7497fc 100644 --- a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx +++ b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx @@ -2315,7 +2315,7 @@ struct HfTaskCharmPolarisation { float centrality = {-1.f}; centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); if (centrality < centralityMin || centrality > centralityMax) { - return; // skip this collision if outside of the centrality range + continue; // skip this collision if outside of the centrality range } registry.fill(HIST("hCentrality"), centrality); @@ -2345,7 +2345,7 @@ struct HfTaskCharmPolarisation { float centrality = {-1.f}; centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); if (centrality < centralityMin || centrality > centralityMax) { - return; // skip this collision if outside of the centrality range + continue; // skip this collision if outside of the centrality range } registry.fill(HIST("hCentrality"), centrality); @@ -2379,7 +2379,7 @@ struct HfTaskCharmPolarisation { for (const auto& collision : collisions) { // loop over reco collisions associated to this gen collision centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); if (centrality < centralityMin || centrality > centralityMax) { - return; // skip this collision if outside of the centrality range + continue; // skip this collision if outside of the centrality range } registry.fill(HIST("hCentrality"), centrality); @@ -2420,7 +2420,7 @@ struct HfTaskCharmPolarisation { for (const auto& collision : collisions) { // loop over reco collisions associated to this gen collision centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); if (centrality < centralityMin || centrality > centralityMax) { - return; // skip this collision if outside of the centrality range + continue; // skip this collision if outside of the centrality range } registry.fill(HIST("hCentrality"), centrality); diff --git a/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx b/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx index a611d7e166a..69c09d88d5f 100644 --- a/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx +++ b/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx @@ -18,6 +18,7 @@ #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGLF/DataModel/mcCentrality.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -52,10 +53,9 @@ namespace o2::aod { namespace ml { -// collision info -DECLARE_SOA_COLUMN(KfptPiFromOmegac, kfptPiFromOmegac, float); -DECLARE_SOA_COLUMN(KfptOmegac, kfptOmegac, float); DECLARE_SOA_COLUMN(InvMassCharmBaryon, invMassCharmBaryon, float); +DECLARE_SOA_COLUMN(KfptOmegac, kfptOmegac, float); +DECLARE_SOA_COLUMN(KfptPiFromOmegac, kfptPiFromOmegac, float); DECLARE_SOA_COLUMN(MlProbOmegac, mlProbOmegac, float); DECLARE_SOA_COLUMN(Cent, cent, float); } // namespace ml @@ -64,27 +64,20 @@ DECLARE_SOA_TABLE(HfKfOmegacML, "AOD", "HFKFOMEGACML", } // namespace o2::aod /// Omegac0 analysis task - struct HfTaskOmegac0ToOmegapi { - Produces kfCandMl; - // ML inference - Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; - Configurable fillCent{"fillCent", false, "Flag to fill centrality information"}; - Configurable fillTree{"fillTree", false, "Fill TTree for local analysis.(Enabled only with ML)"}; + Configurable selectionFlagOmegac0{"selectionFlagOmegac0", true, "Select Omegac0 candidates"}; - Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; - Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; + Configurable yCandGenMax{"yCandGenMax", 0.5, "Max. gen particle rapidity"}; + Configurable yCandRecoMax{"yCandRecoMax", 0.8, "Max. cand. rapidity"}; + Configurable fillTree{"fillTree", false, "Fill tree for local analysis (enabled only with ML)"}; HfHelper hfHelper; SliceCache cache; - using TracksMc = soa::Join; - using Omegac0Cands = soa::Filtered>; using Omegac0CandsKF = soa::Filtered>; using OmegaC0CandsMcKF = soa::Filtered>; - using Omegac0CandsMl = soa::Filtered>; using Omegac0CandsMlKF = soa::Filtered>; using Omegac0CandsMlMcKF = soa::Filtered>; @@ -96,88 +89,83 @@ struct HfTaskOmegac0ToOmegapi { using CollisionsWithFT0M = soa::Join; using CollisionsWithMcLabels = soa::Join; + using McCollisionsWithFT0M = soa::Join; + Filter filterOmegaCToOmegaPiFlag = (aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi))) != static_cast(0); Filter filterOmegaCMatchedRec = nabs(aod::hf_cand_xic0_omegac0::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi)); Filter filterOmegaCMatchedGen = nabs(aod::hf_cand_xic0_omegac0::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi)); + Preslice candOmegacKFPerCollision = aod::hf_cand_xic0_omegac0::collisionId; Preslice candOmegacKFMlPerCollision = aod::hf_cand_xic0_omegac0::collisionId; - PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; - // ThnSparse for ML outputScores and Vars - ConfigurableAxis thnConfigAxisPromptScore{"thnConfigAxisPromptScore", {100, 0, 1}, "Prompt score bins"}; - ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {120, 2.4, 3.1}, "Cand. inv-mass bins"}; - ConfigurableAxis thnConfigAxisPtB{"thnConfigAxisPtB", {1000, 0, 100}, "Cand. beauty mother pTB bins"}; - ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {100, 0, 20}, "Cand. pT bins"}; - ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {20, -1, 1}, "Cand. rapidity bins"}; - ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {100, 0, 100}, "Centrality bins"}; - ConfigurableAxis thnConfigAxisPtPion{"thnConfigAxisPtPion", {100, 0, 10}, "PtPion from Omegac0 bins"}; - ConfigurableAxis thnConfigAxisOrigin{"thnConfigAxisOrigin", {3, -0.5, 2.5}, "Cand. origin type"}; - ConfigurableAxis thnConfigAxisMatchFlag{"thnConfigAxisMatchFlag", {15, -7.5, 7.5}, "Cand. MC Match Flag type"}; - ConfigurableAxis thnConfigAxisGenPtD{"thnConfigAxisGenPtD", {500, 0, 50}, "Gen Pt D"}; - ConfigurableAxis thnConfigAxisGenPtB{"thnConfigAxisGenPtB", {1000, 0, 100}, "Gen Pt B"}; - ConfigurableAxis thnConfigAxisNumPvContr{"thnConfigAxisNumPvContr", {200, -0.5, 199.5}, "Number of PV contributors"}; + ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {700, 2.4, 3.1}, "Cand. inv. mass"}; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {500, 0, 50}, "Cand. pT"}; + ConfigurableAxis thnConfigAxisPtB{"thnConfigAxisPtB", {500, 0, 50}, "Cand. beauty mother pT"}; + ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {20, -1, 1}, "Cand. rapidity"}; + ConfigurableAxis thnConfigAxisOrigin{"thnConfigAxisOrigin", {3, -0.5, 2.5}, "Cand. origin"}; + ConfigurableAxis thnConfigAxisMatchFlag{"thnConfigAxisMatchFlag", {15, -7.5, 7.5}, "Cand. MC match flag"}; + ConfigurableAxis thnConfigAxisNumPvContr{"thnConfigAxisNumPvContr", {200, -0.5, 199.5}, "Coll. num. PV contributors"}; + ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {100, 0, 100}, "Coll. centrality precentile"}; + ConfigurableAxis thnConfigAxisPromptScore{"thnConfigAxisPromptScore", {100, 0, 1}, "Prompt score"}; HistogramRegistry registry{"registry", {}}; void init(InitContext&) { - std::array doprocess{doprocessDataWithKFParticle, doprocessDataWithKFParticleMl, doprocessDataWithKFParticleFT0C, doprocessDataWithKFParticleMlFT0C, doprocessDataWithKFParticleFT0M, doprocessDataWithKFParticleMlFT0M}; - if (std::accumulate(doprocess.begin(), doprocess.end(), 0) > 1) { - LOGP(fatal, "At most one data process function should be enabled at a time."); - } - - std::array doprocessMc{doprocessMcWithKFParticle, doprocessMcWithKFParticleMl}; - if (std::accumulate(doprocessMc.begin(), doprocessMc.end(), 0) > 1) { - LOGP(fatal, "At most one MC process function should be enabled at a time."); - } - - if ((std::accumulate(doprocess.begin(), doprocess.end(), 0) + std::accumulate(doprocessMc.begin(), doprocessMc.end(), 0)) == 0) { - LOGP(fatal, "At least one process function should be enabled."); + std::array doprocess{doprocessDataKFParticle, doprocessDataKFParticleMl, doprocessDataKFParticleFT0C, doprocessDataKFParticleMlFT0C, + doprocessDataKFParticleFT0M, doprocessDataKFParticleMlFT0M, doprocessMcKFParticle, doprocessMcKFParticleMl, + doprocessMcKFParticleFT0M, doprocessMcKFParticleMlFT0M}; + if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { + LOGP(fatal, "One and only one process function should be enabled at a time."); } - const AxisSpec thnAxisMass{thnConfigAxisMass, "inv. mass (#Omega#pi) (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisMass{thnConfigAxisMass, "Inv. mass (#Omega#pi) (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec thnAxisPtB{thnConfigAxisPtB, "#it{p}_{T}^{B} (GeV/#it{c})"}; const AxisSpec thnAxisY{thnConfigAxisY, "y"}; const AxisSpec thnAxisOrigin{thnConfigAxisOrigin, "Origin"}; - const AxisSpec thnAxisMatchFlag{thnConfigAxisMatchFlag, "MatchFlag"}; - const AxisSpec thnAxisGenPtD{thnConfigAxisGenPtD, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtB{thnConfigAxisGenPtB, "#it{p}_{T}^{B} (GeV/#it{c})"}; - const AxisSpec thnAxisNumPvContr{thnConfigAxisNumPvContr, "Number of PV contributors"}; - - if (doprocessMcWithKFParticle || doprocessMcWithKFParticleMl) { - std::vector axesAcc = {thnAxisGenPtD, thnAxisGenPtB, thnAxisY, thnAxisOrigin, thnAxisNumPvContr}; - registry.add("hSparseAcc", "Thn for generated Omega0 from charm and beauty", HistType::kTHnSparseD, axesAcc); - registry.get(HIST("hSparseAcc"))->Sumw2(); - } + const AxisSpec thnAxisMatchFlag{thnConfigAxisMatchFlag, "MC match flag"}; + const AxisSpec thnAxisNumPvContr{thnConfigAxisNumPvContr, "Number of primary vtx. contributors"}; + const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality percentile"}; + const AxisSpec thnAxisCentMc{thnConfigAxisCent, "Centrality percentile (from gen. MC info)"}; + const AxisSpec thnAxisPromptScore{thnConfigAxisPromptScore, "BDT score prompt"}; std::vector axes = {thnAxisMass, thnAxisPt, thnAxisY}; - if (doprocessMcWithKFParticle || doprocessMcWithKFParticleMl) { + std::vector axesMcGen = {thnAxisPt, thnAxisPtB, thnAxisY, thnAxisOrigin}; + + if (doprocessDataKFParticleFT0C || doprocessDataKFParticleMlFT0C || doprocessDataKFParticleFT0M || doprocessDataKFParticleMlFT0M) { + axes.push_back(thnAxisCent); + axes.push_back(thnConfigAxisNumPvContr); + } + + if (doprocessMcKFParticleFT0M || doprocessMcKFParticleMlFT0M) { + axes.push_back(thnAxisCentMc); + axes.push_back(thnConfigAxisNumPvContr); + axesMcGen.push_back(thnAxisCentMc); + axesMcGen.push_back(thnConfigAxisNumPvContr); + } + + if (doprocessMcKFParticle || doprocessMcKFParticleMl || doprocessMcKFParticleFT0M || doprocessMcKFParticleMlFT0M) { + registry.add("hMcGen", "Gen. #Omega_{c}^{0} from charm and beauty", HistType::kTHnSparseD, axesMcGen); + registry.get(HIST("hMcGen"))->Sumw2(); + + if (doprocessMcKFParticleFT0M || doprocessMcKFParticleMlFT0M) { + registry.add("hMcGenWithRecoColl", "Gen. #Omega_{c}^{0} from charm and beauty (associated to a reco collision)", HistType::kTHnSparseD, axesMcGen); + registry.add("hNumRecoCollPerMcColl", "Number of reco collisions associated to a mc collision;Num. reco. coll. per Mc coll.;", {HistType::kTH1D, {{10, -0.5, 9.5}}}); + registry.get(HIST("hMcGenWithRecoColl"))->Sumw2(); + } + axes.push_back(thnAxisPtB); axes.push_back(thnAxisOrigin); axes.push_back(thnAxisMatchFlag); - axes.push_back(thnAxisNumPvContr); } - if (applyMl) { - const AxisSpec thnAxisPromptScore{thnConfigAxisPromptScore, "BDT score prompt."}; - axes.insert(axes.begin(), thnAxisPromptScore); - registry.add("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsOmegac0Type", "Thn for Omegac0 candidates", HistType::kTHnSparseD, axes); - registry.get(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsOmegac0Type"))->Sumw2(); - } else { - registry.add("hMassVsPtVsPtBVsYVsOriginVsOmegac0Type", "Thn for Omegac0 candidates", HistType::kTHnSparseF, axes); - registry.get(HIST("hMassVsPtVsPtBVsYVsOriginVsOmegac0Type"))->Sumw2(); - } - if (fillCent) { - const AxisSpec thnAxisPromptScore{thnConfigAxisPromptScore, "BDT score prompt."}; - const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality."}; - const AxisSpec thnAxisPtPion{thnConfigAxisPtPion, "Pt of Pion from Omegac0."}; - std::vector axesWithBdtCent = {thnAxisPromptScore, thnAxisMass, thnAxisPt, thnAxisY, thnAxisCent, thnAxisPtPion, thnConfigAxisNumPvContr}; - std::vector axesWithCent = {thnAxisMass, thnAxisPt, thnAxisY, thnAxisCent, thnAxisPtPion, thnConfigAxisNumPvContr}; - registry.add("hBdtScoreVsMassVsPtVsYVsCentVsPtPion", "Thn for Omegac0 candidates with BDT&Cent&pTpi", HistType::kTHnSparseD, axesWithBdtCent); - registry.add("hMassVsPtVsYVsCentVsPtPion", "Thn for Omegac0 candidates with Cent&pTpi", HistType::kTHnSparseD, axesWithCent); - registry.get(HIST("hBdtScoreVsMassVsPtVsYVsCentVsPtPion"))->Sumw2(); - registry.get(HIST("hMassVsPtVsYVsCentVsPtPion"))->Sumw2(); + + if (doprocessDataKFParticleMl || doprocessDataKFParticleMlFT0C || doprocessDataKFParticleMlFT0M || doprocessMcKFParticleMl || doprocessMcKFParticleMlFT0M) { + axes.push_back(thnAxisPromptScore); } + + registry.add("hReco", "Reco. #Omega_{c}^{0} candidates", HistType::kTHnSparseD, axes); + registry.get(HIST("hReco"))->Sumw2(); } /// Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table) @@ -189,21 +177,22 @@ struct HfTaskOmegac0ToOmegapi { return o2::hf_centrality::getCentralityColl(collision); } - template - void processData(const CandType& candidates, CollType const&) + template + void processData(const CandType& candidates) { for (const auto& candidate : candidates) { if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { continue; } + if (yCandRecoMax >= 0. && std::abs(candidate.kfRapOmegac()) > yCandRecoMax) { continue; } if constexpr (applyMl) { - registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsOmegac0Type"), candidate.mlProbOmegac()[0], candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac()); + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), candidate.mlProbOmegac()[0]); } else { - registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsOmegac0Type"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac()); + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac()); } } } @@ -212,57 +201,37 @@ struct HfTaskOmegac0ToOmegapi { void processDataCent(const CandType& candidates, CollType const& collisions) { for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto groupedOmegacCandidates = applyMl - ? candidates.sliceBy(candOmegacKFMlPerCollision, thisCollId) - : candidates.sliceBy(candOmegacKFPerCollision, thisCollId); + auto groupedOmegacCandidates = applyMl ? candidates.sliceBy(candOmegacKFMlPerCollision, thisCollId) : candidates.sliceBy(candOmegacKFPerCollision, thisCollId); auto numPvContributors = collision.numContrib(); for (const auto& candidate : groupedOmegacCandidates) { if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { continue; } + if (yCandRecoMax >= 0. && std::abs(candidate.kfRapOmegac()) > yCandRecoMax) { continue; } + float cent = evaluateCentralityColl(collision); + if constexpr (applyMl) { + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), + cent, numPvContributors, candidate.mlProbOmegac()[0]); if (fillTree) { - kfCandMl(candidate.invMassCharmBaryon(), - candidate.ptCharmBaryon(), - candidate.kfptPiFromOmegac(), - candidate.mlProbOmegac()[0], - cent); - } else { - registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsCentVsPtPion"), - candidate.mlProbOmegac()[0], - candidate.invMassCharmBaryon(), - candidate.ptCharmBaryon(), - candidate.kfRapOmegac(), - cent, - candidate.kfptPiFromOmegac(), - numPvContributors); + kfCandMl(candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfptPiFromOmegac(), candidate.mlProbOmegac()[0], cent); } } else { - registry.fill(HIST("hMassVsPtVsYVsCentVsPtPion"), - candidate.invMassCharmBaryon(), - candidate.ptCharmBaryon(), - candidate.kfRapOmegac(), - cent, - candidate.kfptPiFromOmegac(), - numPvContributors); + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), + cent, numPvContributors); } } } } - template - void processMc(const CandType& candidates, - Omegac0Gen const& mcParticles, - TracksMc const&, - CollType const& collisions, - aod::McCollisions const&) + template + void processMc(const CandType& candidates, Omegac0Gen const& mcParticles) { // MC rec. for (const auto& candidate : candidates) { @@ -273,13 +242,54 @@ struct HfTaskOmegac0ToOmegapi { continue; } - auto numPvContributors = candidate.template collision_as().numContrib(); + if constexpr (applyMl) { + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), candidate.mlProbOmegac()[0]); + + } else { + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec()); + } + } + + // MC gen. + for (const auto& particle : mcParticles) { + if (yCandGenMax >= 0. && std::abs(particle.rapidityCharmBaryonGen()) > yCandGenMax) { + continue; + } + + auto ptGen = particle.pt(); + auto yGen = particle.rapidityCharmBaryonGen(); + + if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("hMcGen"), ptGen, -1., yGen, RecoDecay::OriginType::Prompt); + } else { + float ptGenB = mcParticles.rawIteratorAt(particle.idxBhadMotherPart()).pt(); + registry.fill(HIST("hMcGen"), ptGen, ptGenB, yGen, RecoDecay::OriginType::NonPrompt); + } + } + } + + template + void processMcCent(const CandType& candidates, Omegac0Gen const& mcParticles, + CollisionsWithMcLabels const& collisions, McCollisionWithCents const&) + { + // MC rec. + for (const auto& candidate : candidates) { + if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { + continue; + } + if (yCandRecoMax >= 0. && std::abs(candidate.kfRapOmegac()) > yCandRecoMax) { + continue; + } + + auto collision = candidate.template collision_as(); + uint16_t numPvContributors = collision.numContrib(); + float mcCent = evaluateCentralityColl(collision.template mcCollision_as()); if constexpr (applyMl) { - registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsOmegac0Type"), candidate.mlProbOmegac()[0], candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), numPvContributors); + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), mcCent, numPvContributors, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), candidate.mlProbOmegac()[0]); } else { - registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsOmegac0Type"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec(), numPvContributors); + registry.fill(HIST("hReco"), candidate.invMassCharmBaryon(), candidate.ptCharmBaryon(), candidate.kfRapOmegac(), mcCent, numPvContributors, candidate.ptBhadMotherPart(), candidate.originMcRec(), candidate.flagMcMatchRec()); } } @@ -291,83 +301,108 @@ struct HfTaskOmegac0ToOmegapi { auto ptGen = particle.pt(); auto yGen = particle.rapidityCharmBaryonGen(); + auto mcCollision = particle.template mcCollision_as(); - unsigned maxNumContrib = 0; - const auto& recoCollsPerMcColl = collisions.sliceBy(colPerMcCollision, particle.mcCollision().globalIndex()); + int maxNumContrib = 0; + const auto& recoCollsPerMcColl = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); for (const auto& recCol : recoCollsPerMcColl) { maxNumContrib = recCol.numContrib() > maxNumContrib ? recCol.numContrib() : maxNumContrib; } + float mcCent = evaluateCentralityColl(mcCollision); + if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hSparseAcc"), ptGen, -1., yGen, RecoDecay::OriginType::Prompt, maxNumContrib); + registry.fill(HIST("hMcGen"), ptGen, -1., yGen, RecoDecay::OriginType::Prompt, mcCent, maxNumContrib); } else { float ptGenB = mcParticles.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hSparseAcc"), ptGen, ptGenB, yGen, RecoDecay::OriginType::NonPrompt, maxNumContrib); + registry.fill(HIST("hMcGen"), ptGen, ptGenB, yGen, RecoDecay::OriginType::NonPrompt, mcCent, maxNumContrib); + } + + registry.fill(HIST("hNumRecoCollPerMcColl"), recoCollsPerMcColl.size()); + + // fill sparse only for gen particles associated to a reconstructed collision + if (recoCollsPerMcColl.size() >= 1) { + if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("hMcGenWithRecoColl"), ptGen, -1., yGen, RecoDecay::OriginType::Prompt, mcCent, maxNumContrib); + } else { + float ptGenB = mcParticles.rawIteratorAt(particle.idxBhadMotherPart()).pt(); + registry.fill(HIST("hMcGenWithRecoColl"), ptGen, ptGenB, yGen, RecoDecay::OriginType::NonPrompt, mcCent, maxNumContrib); + } } } } - void processDataWithKFParticle(Omegac0CandsKF const& candidates, - Collisions const& collisions) + void processDataKFParticle(Omegac0CandsKF const& candidates) { - processData(candidates, collisions); + processData(candidates); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticle, "process HfTaskOmegac0ToOmegapi with KFParticle", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataKFParticle, "process data with KFParticle", false); - void processDataWithKFParticleMl(Omegac0CandsMlKF const& candidates, - Collisions const& collisions) + void processDataKFParticleMl(Omegac0CandsMlKF const& candidates) { - processData(candidates, collisions); + processData(candidates); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleMl, "process HfTaskOmegac0ToOmegapi with KFParticle and ML selections", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataKFParticleMl, "process data with KFParticle, ML selections", false); - void processDataWithKFParticleFT0C(Omegac0CandsKF const& candidates, - CollisionsWithFT0C const& collisions) + void processDataKFParticleFT0C(Omegac0CandsKF const& candidates, + CollisionsWithFT0C const& collisions) { processDataCent(candidates, collisions); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleFT0C, "process HfTaskOmegac0ToOmegapi with KFParticle and with FT0C centrality", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataKFParticleFT0C, "process data with KFParticle, FT0C centrality", false); - void processDataWithKFParticleMlFT0C(Omegac0CandsMlKF const& candidates, - CollisionsWithFT0C const& collisions) + void processDataKFParticleMlFT0C(Omegac0CandsMlKF const& candidates, + CollisionsWithFT0C const& collisions) { processDataCent(candidates, collisions); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleMlFT0C, "process HfTaskOmegac0ToOmegapi with KFParticle and ML selections and with FT0C centrality", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataKFParticleMlFT0C, "process data with KFParticle, ML selections, FT0C centrality", false); - void processDataWithKFParticleFT0M(Omegac0CandsKF const& candidates, - CollisionsWithFT0M const& collisions) + void processDataKFParticleFT0M(Omegac0CandsKF const& candidates, + CollisionsWithFT0M const& collisions) { processDataCent(candidates, collisions); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleFT0M, "process HfTaskOmegac0ToOmegapi with KFParticle and with FT0M centrality", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataKFParticleFT0M, "process data with KFParticle, FT0M centrality", false); - void processDataWithKFParticleMlFT0M(Omegac0CandsMlKF const& candidates, - CollisionsWithFT0M const& collisions) + void processDataKFParticleMlFT0M(Omegac0CandsMlKF const& candidates, + CollisionsWithFT0M const& collisions) { processDataCent(candidates, collisions); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleMlFT0M, "process HfTaskOmegac0ToOmegapi with KFParticle and ML selections and with FT0M centrality", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataKFParticleMlFT0M, "process data with KFParticle, ML selections, FT0M centrality", false); + + void processMcKFParticle(OmegaC0CandsMcKF const& omegaC0CandidatesMcKF, + Omegac0Gen const& mcParticles) + { + processMc(omegaC0CandidatesMcKF, mcParticles); + } + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processMcKFParticle, "Process MC with KFParticle", false); + + void processMcKFParticleMl(Omegac0CandsMlMcKF const& omegac0CandidatesMlMcKF, + Omegac0Gen const& mcParticles) + { + processMc(omegac0CandidatesMlMcKF, mcParticles); + } + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processMcKFParticleMl, "Process MC with KFParticle, ML selections", false); - void processMcWithKFParticle(OmegaC0CandsMcKF const& omegaC0CandidatesMcKF, + void processMcKFParticleFT0M(OmegaC0CandsMcKF const& omegaC0CandidatesMcKF, Omegac0Gen const& mcParticles, - TracksMc const& tracks, CollisionsWithMcLabels const& collisions, - aod::McCollisions const& mcCollisions) + McCollisionsWithFT0M const& mcCollisions) { - processMc(omegaC0CandidatesMcKF, mcParticles, tracks, collisions, mcCollisions); + processMcCent(omegaC0CandidatesMcKF, mcParticles, collisions, mcCollisions); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processMcWithKFParticle, "Process MC with KFParticle", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processMcKFParticleFT0M, "Process MC with KFParticle, FT0M centrality (from MC)", false); - void processMcWithKFParticleMl(Omegac0CandsMlMcKF const& omegac0CandidatesMlMcKF, + void processMcKFParticleMlFT0M(Omegac0CandsMlMcKF const& omegac0CandidatesMlMcKF, Omegac0Gen const& mcParticles, - TracksMc const& tracks, CollisionsWithMcLabels const& collisions, - aod::McCollisions const& mcCollisions) + McCollisionsWithFT0M const& mcCollisions) { - processMc(omegac0CandidatesMlMcKF, mcParticles, tracks, collisions, mcCollisions); + processMcCent(omegac0CandidatesMlMcKF, mcParticles, collisions, mcCollisions); } - PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processMcWithKFParticleMl, "Process MC with KFParticle and ML selections", false); + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processMcKFParticleMlFT0M, "Process MC with KFParticle, ML selections, FT0M centrality (from MC)", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskSigmac.cxx b/PWGHF/D2H/Tasks/taskSigmac.cxx index b14d0640c88..e3f0926fac8 100644 --- a/PWGHF/D2H/Tasks/taskSigmac.cxx +++ b/PWGHF/D2H/Tasks/taskSigmac.cxx @@ -805,11 +805,6 @@ struct HfTaskSigmac { /// reconstructed Σc0,++ matched to MC for (const auto& candSc : candidatesSc) { - /// Candidate selected as Σc0 and/or Σc++ - if (!(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)) && !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)) && // Σc0,++(2455) - !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi)) && !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi))) { // Σc0,++(2520) - continue; - } /// rapidity selection on Σc0,++ /// NB: since in data we cannot tag Sc(2455) and Sc(2520), then we use only Sc(2455) for y selection on reconstructed signal if (yCandRecoMax >= 0. && std::abs(hfHelper.ySc0(candSc)) > yCandRecoMax && std::abs(hfHelper.yScPlusPlus(candSc)) > yCandRecoMax) { diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 9fddeb3551d..37c96d5627a 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -982,8 +982,6 @@ enum DecayType { DplusToPiKPi = 0, XicToPKPi, N3ProngDecays }; // always keep N3ProngDecays at the end -static constexpr int DstarToPiKPiBkg = DecayType::N3ProngDecays; - // Ds± → K± K∓ π± or D± → K± K∓ π± enum DecayChannelDToKKPi { @@ -2257,7 +2255,8 @@ DECLARE_SOA_TABLE(HfCandB0Base, "AOD", "HFCANDB0BASE", DECLARE_SOA_TABLE(HfCandB0DStar, "AOD", "HFCANDB0DSTAR", // general columns HFCAND_COLUMNS, - /* prong 2 */ hf_cand::ImpactParameterNormalised2, + /* prong 2 */ + hf_cand::ImpactParameterNormalised2, hf_cand::PtProng2, hf_cand::Pt2Prong2, hf_cand::PVectorProng2, @@ -2270,6 +2269,7 @@ DECLARE_SOA_TABLE(HfCandB0DStar, "AOD", "HFCANDB0DSTAR", /* dynamic columns */ hf_cand_3prong::M, hf_cand_3prong::M2, + hf_cand_2prong::ImpactParameterProduct, hf_cand_3prong::ImpactParameterProngSqSum, /* dynamic columns that use candidate momentum components */ hf_cand::Pt, diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index 7f5786ee1f6..125b0fb7286 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -231,10 +231,12 @@ DECLARE_SOA_TABLE(HfSelJpsi, "AOD", "HFSELJPSI", //! namespace hf_sel_candidate_lc_to_k0s_p { DECLARE_SOA_COLUMN(IsSelLcToK0sP, isSelLcToK0sP, int); +DECLARE_SOA_COLUMN(MlProbLcToK0sP, mlProbLcToK0sP, std::vector); //! } // namespace hf_sel_candidate_lc_to_k0s_p - DECLARE_SOA_TABLE(HfSelLcToK0sP, "AOD", "HFSELLCK0SP", //! hf_sel_candidate_lc_to_k0s_p::IsSelLcToK0sP); +DECLARE_SOA_TABLE(HfMlLcToK0sP, "AOD", "HFMLLcK0sP", //! + hf_sel_candidate_lc_to_k0s_p::MlProbLcToK0sP); namespace hf_sel_candidate_b0 { diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index 39a3231977c..d48cd0f9d10 100644 --- a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h +++ b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h @@ -24,6 +24,7 @@ namespace hf_collisions_reduced { DECLARE_SOA_COLUMN(NumPvContrib, numPvContrib, int); //! Event multiplicity from PV contributors DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); //! Event multiplicity +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Event centrality DECLARE_SOA_COLUMN(PosZ, posZ, float); //! Primary vertex z position } // namespace hf_collisions_reduced @@ -34,6 +35,13 @@ DECLARE_SOA_TABLE(HfcRedCollisions, "AOD", "HFCREDCOLLISION", //! Table with col aod::hf_collisions_reduced::NumPvContrib, aod::hf_collisions_reduced::PosZ); +DECLARE_SOA_TABLE(HfcRedFlowColls, "AOD", "HFCREDFLOWCOLL", //! Table with collision info + soa::Index<>, + aod::hf_collisions_reduced::Multiplicity, + aod::hf_collisions_reduced::NumPvContrib, + aod::hf_collisions_reduced::Centrality, + aod::hf_collisions_reduced::PosZ); + using HfcRedCollision = HfcRedCollisions::iterator; // DECLARE_SOA_TABLE(HfCandColCounts, "AOD", "HFCANDCOLCOUNT", //! Table with number of collisions which contain at least one candidate @@ -41,16 +49,20 @@ using HfcRedCollision = HfcRedCollisions::iterator; namespace hf_candidate_reduced { -DECLARE_SOA_INDEX_COLUMN(HfcRedCollision, hfcRedCollision); //! ReducedCollision index -DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Prong 0 index -DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Prong 1 index -DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Prong2 index -DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candidate -DECLARE_SOA_COLUMN(EtaCand, etaCand, float); //! Eta of the candidate -DECLARE_SOA_COLUMN(PtCand, ptCand, float); //! Pt of the candidate -DECLARE_SOA_COLUMN(InvMassDs, invMassDs, float); //! Invariant mass of Ds candidate -DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis -DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for backgronud hypothesis +DECLARE_SOA_INDEX_COLUMN(HfcRedCollision, hfcRedCollision); //! ReducedCollision index +DECLARE_SOA_INDEX_COLUMN(HfcRedFlowColl, hfcRedFlowColl); //! ReducedCollision index +DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Prong 0 index +DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Prong 1 index +DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Prong2 index +DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candidate +DECLARE_SOA_COLUMN(EtaCand, etaCand, float); //! Eta of the candidate +DECLARE_SOA_COLUMN(PtCand, ptCand, float); //! Pt of the candidate +DECLARE_SOA_COLUMN(InvMassDs, invMassDs, float); //! Invariant mass of Ds candidate +DECLARE_SOA_COLUMN(InvMassCharmHad, invMassCharmHad, float); //! Invariant mass of CharmHad candidate +DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis +DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for backgronud hypothesis +DECLARE_SOA_COLUMN(BdtScore0, bdtScore0, float); //! First BDT output score +DECLARE_SOA_COLUMN(BdtScore1, bdtScore1, float); //! Second BDT output score } // namespace hf_candidate_reduced DECLARE_SOA_TABLE(DsCandReduceds, "AOD", "DSCANDREDUCED", //! Table with Ds candidate info soa::Index<>, @@ -69,6 +81,23 @@ DECLARE_SOA_TABLE(DsCandSelInfos, "AOD", "DSCANDSELINFO", //! Table with Ds cand aod::hf_candidate_reduced::BdtScorePrompt, aod::hf_candidate_reduced::BdtScoreBkg); +DECLARE_SOA_TABLE(HfcRedCharmHads, "AOD", "HFCREDCHARMHAD", //! Table with charm hadron candidate info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_candidate_reduced::PhiCand, + aod::hf_candidate_reduced::EtaCand, + aod::hf_candidate_reduced::PtCand, + aod::hf_candidate_reduced::InvMassCharmHad, + aod::hf_candidate_reduced::Prong0Id, + aod::hf_candidate_reduced::Prong1Id, + aod::hf_candidate_reduced::Prong2Id); + +DECLARE_SOA_TABLE(HfcRedCharmMls, "AOD", "HFCREDCHARMML", //! Table with charm hadron candidate selection info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_candidate_reduced::BdtScore0, + aod::hf_candidate_reduced::BdtScore1); + namespace hf_assoc_track_reduced { DECLARE_SOA_COLUMN(OriginTrackId, originTrackId, int); //! Original track index @@ -97,6 +126,23 @@ DECLARE_SOA_TABLE(AssocTrackSels, "AOD", "ASSOCTRACKSEL", //! Table with associa aod::hf_assoc_track_reduced::ItsNCls, aod::hf_assoc_track_reduced::DcaXY, aod::hf_assoc_track_reduced::DcaZ) + +DECLARE_SOA_TABLE(HfcRedTrkAssoc, "AOD", "HFCREDTRKASSOC", //! Table with associated track info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_assoc_track_reduced::OriginTrackId, + aod::hf_assoc_track_reduced::PhiAssocTrack, + aod::hf_assoc_track_reduced::EtaAssocTrack, + aod::hf_assoc_track_reduced::PtAssocTrack); + +DECLARE_SOA_TABLE(HfcRedTrkSels, "AOD", "HFCREDTRKSELS", //! Table with associated track info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_assoc_track_reduced::NTpcCrossedRows, + aod::hf_assoc_track_reduced::ItsClusterMap, + aod::hf_assoc_track_reduced::ItsNCls, + aod::hf_assoc_track_reduced::DcaXY, + aod::hf_assoc_track_reduced::DcaZ) } // namespace o2::aod #endif // PWGHF_HFC_DATAMODEL_DERIVEDDATACORRELATIONTABLES_H_ diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 99f2c4fb152..eff0f6557b3 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -44,6 +44,11 @@ o2physics_add_dpl_workflow(correlator-ds-hadrons PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(correlator-flow-charm-hadrons + SOURCES correlatorFlowCharmHadrons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(correlator-ds-hadrons-reduced SOURCES correlatorDsHadronsReduced.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/TableProducer/correlatorDstarHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDstarHadrons.cxx index 1a4cafe02ac..6f763420bcd 100644 --- a/PWGHF/HFC/TableProducer/correlatorDstarHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDstarHadrons.cxx @@ -196,12 +196,15 @@ struct HfCorrelatorDstarHadrons { LOGP(fatal, "One and only one process function must be enabled at a time."); } + AxisSpec axisSpecMultFT0M{binsMultiplicity, "Multiplicity in FT0M", "multFT0M"}; + invMassDstarParticle = -999.0; invMassD0Particle = -999.0; binNumber = -2; binningScheme = {{binsZVtx, binsMultiplicity}, true}; + registry.add("QA/hMultFT0M", "Multiplicity distribution in FT0M", {HistType::kTH1D, {axisSpecMultFT0M}}); registry.add("QA/hCandsPerCol", "Candidates per Collision", {HistType::kTH1D, {{100, 0.0, 100.0}}}); registry.add("QA/hAssoTracksPerCol", "Tracks per Collision", {HistType::kTH1D, {{1000, 0.0, 1000.0}}}); registry.add("QA/hCandsVsTracksPerCol", "Candidates vs Tracks per Collision", {HistType::kTHnSparseF, {{100, 0.0, 100.0}, {1000, 0.0, 1000.0}}}); @@ -239,6 +242,7 @@ struct HfCorrelatorDstarHadrons { } // endif registry.fill(HIST("hTriggerColCandPairCounts"), 1); // counting number of trigger particle + registry.fill(HIST("QA/hMultFT0M"), collision.multFT0M()); registry.fill(HIST("QA/hCandsPerCol"), candidatesPerCol.size()); registry.fill(HIST("QA/hAssoTracksPerCol"), tracksPerCol.size()); registry.fill(HIST("QA/hCandsVsTracksPerCol"), candidatesPerCol.size(), tracksPerCol.size()); diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx new file mode 100644 index 00000000000..ec5f2a40c19 --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx @@ -0,0 +1,272 @@ +// 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 correlatorFlowCharmHadrons.cxx +/// \brief CharmHadrons-Hadrons correlator tree creator for data and MC-reco analyses +/// \author Marcello Di Costanzo , Politecnico and INFN Torino +/// \author Stefano Politanò , CERN + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" +#include "PWGHF/Utils/utilsEvSelHf.h" + +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace o2; +using namespace o2::hf_centrality; +using namespace o2::hf_evsel; + +enum DecayChannel { + DplusToPiKPi = 0, + DsToKKPi, + DsToPiKK +}; + +/// Code to select collisions with at least one Ds meson +struct HfCorrelatorFlowCharmHadrons { + Produces rowCollisions; + Produces rowCharmCandidates; + Produces rowCharmCandidatesMl; + Produces rowAssocTrackReduced; + Produces rowAssocTrackSelInfo; + + Configurable centEstimator{"centEstimator", 2, "Centrality estimation (FT0A: 1, FT0C: 2, FT0M: 3, FV0A: 4)"}; + Configurable selectionFlag{"selectionFlag", 1, "Selection Flag for hadron (e.g. 1 for skimming, 3 for topo. and kine., 7 for PID)"}; + Configurable forceCharmInCollision{"forceCharmInCollision", false, "Flag to force charm in collision"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; + Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; + Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; + Configurable ptCandMax{"ptCandMax", 24., "max. cand. pT"}; + Configurable etaTrackMax{"etaTrackMax", 1., "max. track eta"}; + Configurable ptTrackMin{"ptTrackMin", 0.15, "min. track pT"}; + Configurable ptTrackMax{"ptTrackMax", 5., "max. track pT"}; + Configurable dcaXYTrackMax{"dcaXYTrackMax", 1., "max. track DCA XY"}; + Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. track DCA Z"}; + + HfHelper hfHelper; + HfEventSelection hfEvSel; // event selection and monitoring + o2::framework::Service ccdb; + SliceCache cache; + + double massCharm{0.}; + + using CollsWithCentMult = soa::Join; + using CandDsDataWMl = soa::Filtered>; + using CandDplusDataWMl = soa::Filtered>; + using TracksData = soa::Filtered>; + + Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag; + Filter filterSelectTrackData = (nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin) && (aod::track::pt < ptTrackMax) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); + + Preslice candsDsPerCollWMl = aod::hf_cand::collisionId; + Preslice candsDplusPerCollWMl = aod::hf_cand::collisionId; + Preslice trackIndicesPerColl = aod::track::collisionId; + + Partition selectedDsToKKPiWMl = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; + Partition selectedDsToPiKKWMl = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + + HistogramRegistry registry{"registry", {}}; + + void init(InitContext&) + { + if (doprocessDplusWithMl) { + massCharm = o2::constants::physics::MassDPlus; + } else if (doprocessDsWithMl) { + massCharm = o2::constants::physics::MassDS; + } + + hfEvSel.addHistograms(registry); // collision monitoring + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + }; // end init + + /// Check event selections for collision and fill the collision table + /// \param collision is the collision + template + bool checkAndFillCollision(Coll const& collision) + { + float cent{-1.f}; + float mult{-1.f}; + o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; + if (centEstimator == CentralityEstimator::FT0A) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFT0A(); + } else if (centEstimator == CentralityEstimator::FT0C) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFT0C(); + } else if (centEstimator == CentralityEstimator::FT0M) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFT0M(); + } else if (centEstimator == CentralityEstimator::FV0A) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFV0A(); + } else { + LOG(fatal) << "Centrality estimator not recognized for collision selection"; + std::abort(); + } + hfEvSel.fillHistograms(collision, collRejMask, cent); + if (collRejMask != 0) { + return false; + } + rowCollisions(mult, collision.numContrib(), cent, collision.posZ()); + return true; + } + + /// Get charm hadron candidate mass + /// \param candidate is the charm hadron candidate + template + double getCandMass(const TCand& candidate) + { + if constexpr (channel == DecayChannel::DsToKKPi) { + return hfHelper.invMassDsToKKPi(candidate); + } + if constexpr (channel == DecayChannel::DsToPiKK) { + return hfHelper.invMassDsToPiKK(candidate); + } + if constexpr (channel == DecayChannel::DplusToPiKPi) { + return hfHelper.invMassDplusToPiKPi(candidate); + } + return -1.; + } + + /// Get charm hadron bdt scores + /// \param candidate is the charm hadron candidate + template + std::vector getCandMlScores(const TCand& candidate) + { + std::vector outputMl{-999., -999.}; + if constexpr (channel == DecayChannel::DsToKKPi) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; + } + } + if constexpr (channel == DecayChannel::DsToPiKK) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; + } + } + if constexpr (channel == DecayChannel::DplusToPiKPi) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; + } + } + return outputMl; + } + + /// Fill charm hadron tables + /// \param candidates are the selected charm hadron candidates + template + void fillCharmHadronTables(TCand const& candidates) + { + int indexRedColl = rowCollisions.lastIndex(); + for (const auto& candidate : candidates) { + if (std::abs(candidate.y(massCharm)) > yCandMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { + continue; + } + double massCand = getCandMass(candidate); + rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); + + std::vector outputMl = getCandMlScores(candidate); + rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); + } + } + + /// Fill tracks tables + /// \param tracks are the selected tracks + template + void fillTracksTables(TTrack const& tracks) + { + int indexRedColl = rowCollisions.lastIndex(); + for (const auto& track : tracks) { + if (!track.isGlobalTrackWoDCA()) { + continue; + } + rowAssocTrackReduced(indexRedColl, track.globalIndex(), track.phi(), track.eta(), track.pt()); + rowAssocTrackSelInfo(indexRedColl, track.tpcNClsCrossedRows(), track.itsClusterMap(), track.itsNCls(), track.dcaXY(), track.dcaZ()); + } + } + + // Dplus with ML selections + void processDplusWithMl(CollsWithCentMult const& colls, + CandDplusDataWMl const& candsDplus, + TracksData const& tracks) + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsCThisColl = candsDplus.sliceBy(candsDplusPerCollWMl, thisCollId); + if (forceCharmInCollision && candsCThisColl.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } + auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); + fillCharmHadronTables(candsCThisColl); + fillTracksTables(trackIdsThisColl); + } + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplusWithMl, "Process Dplus candidates with ML info", false); + + // Ds with ML selections + void processDsWithMl(CollsWithCentMult const& colls, + TracksData const& tracks, + CandDsDataWMl const&) + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsDsToKKPiWMl = selectedDsToKKPiWMl->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); + auto candsDsToPiKKWMl = selectedDsToPiKKWMl->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); + if (forceCharmInCollision && candsDsToKKPiWMl.size() < 1 && candsDsToPiKKWMl.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } + auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); + fillCharmHadronTables(candsDsToPiKKWMl); + fillCharmHadronTables(candsDsToKKPiWMl); + fillTracksTables(trackIdsThisColl); + } + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDsWithMl, "Process Ds candidates with ML info", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index 3f10c0462fa..baca2b26b99 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -56,6 +56,7 @@ #include #include #include +#include #include using namespace o2; @@ -113,9 +114,10 @@ struct HfTaskElectronWeakBoson { Configurable isTHnElectron{"isTHnElectron", true, "Enables THn for electrons"}; Configurable ptTHnThresh{"ptTHnThresh", 5.0, "Threshold for THn make"}; - // Skimmed dataset processing configurations + // Skimmed (trigger) dataset processing configurations Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", true, "Enables processing of skimmed datasets"}; Configurable cfgTriggerName{"cfgTriggerName", "fGammaHighPtEMCAL", "Trigger of interest (comma separated for multiple)"}; + Configurable applySel8{"applySel8", true, "Apply sel8 filter or not"}; // CCDB service configurations Configurable cfgCCDBPath{"cfgCCDBPath", "Users/m/mpuccio/EventFiltering/OTS/", "Path to CCDB for trigger data"}; @@ -130,19 +132,20 @@ struct HfTaskElectronWeakBoson { Configurable enableCentralityAnalysis{"enableCentralityAnalysis", true, "Enable centrality-dependent analysis"}; Configurable centralityMin{"centralityMin", -1, "minimum cut on centrality selection"}; Configurable centralityMax{"centralityMax", 101, "maximum cut on centrality selection"}; + Configurable> centralityBins{"centralityBins", {0, 20, 60, 100}, "centrality bins"}; + // QA for Z->ee + Configurable enableZeeRecoQA{"enableZeeRecoQA", false, "Enable QA for Z->ee reconstruction"}; // CCDB service object Service ccdb; struct HfElectronCandidate { - float pt, eta, phi, energy; - int charge; - HfElectronCandidate(float ptr, float e, float ph, float en, int ch) - : pt(ptr), eta(e), phi(ph), energy(en), charge(ch) {} - - int sign() const { return charge; } + float pt, eta, phi, eop, energyIso, momIso, ntrackIso; + HfElectronCandidate(float ptr, float e, float ph, float ep, float eiso, float piso, int ntrkiso) + : pt(ptr), eta(e), phi(ph), eop(ep), energyIso(eiso), momIso(piso), ntrackIso(ntrkiso) {} }; std::vector selectedElectronsIso; + std::vector selectedPositronsIso; std::vector selectedElectronsAss; struct HfZeeCandidate { @@ -161,8 +164,7 @@ struct HfTaskElectronWeakBoson { // pp // using TrackEle = o2::soa::Filtered>; - // Filter - Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter eventFilter = (applySel8 ? (o2::aod::evsel::sel8 == true) : (o2::aod::evsel::sel8 == o2::aod::evsel::sel8)); Filter posZFilter = (nabs(o2::aod::collision::posZ) < vtxZ); Filter etafilter = (aod::track::eta < etaTrMax) && (aod::track::eta > etaTrMin); @@ -209,6 +211,9 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisCounter{1, 0, 1, "events"}; const AxisSpec axisEta{20, -1.0, 1.0, "#eta"}; const AxisSpec axisPt{nBinsPt, 0, binPtmax, "p_{T}"}; + const AxisSpec axisPtZee{60, 20, 80, "p_{T}"}; + const AxisSpec axisPtZele{60, 20, 80, "p_{T,ele} (GeV/c)"}; + const AxisSpec axisPtZpos{60, 20, 80, "p_{T,pos} (GeV/c)"}; const AxisSpec axisNsigma{100, -5, 5, "N#sigma"}; const AxisSpec axisDedx{150, 0, 150, "dEdx"}; const AxisSpec axisE{nBinsE, 0, binEmax, "Energy"}; @@ -218,20 +223,30 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisdR{20, 0.0, 0.2, "dR"}; const AxisSpec axisNcell{50, 0.0, 50.0, "Ncell"}; const AxisSpec axisPhi{350, 0, 7, "Phi"}; - const AxisSpec axisEop{200, 0, 2, "Eop"}; + const AxisSpec axisEop{200, 0, 2, "E/p"}; + const AxisSpec axisEopZele{200, 0, 2, "E/p electon"}; + const AxisSpec axisEopZpos{200, 0, 2, "E/p positron"}; const AxisSpec axisChi2{250, 0.0, 25.0, "#chi^{2}"}; const AxisSpec axisCluster{100, 0.0, 200.0, "counts"}; const AxisSpec axisITSNCls{10, 0.0, 10, "counts"}; const AxisSpec axisEMCtime{100, -50.0, 50, "EMC time"}; - const AxisSpec axisIsoEnergy{100, 0, 1.0, "Isolation energy(GeV/C)"}; - const AxisSpec axisIsoTrack{15, -0.5, 14.5, "Isolation Track"}; - const AxisSpec axisInvMassZ{150, 0, 150, "M_{ee} (GeV/c^{2})"}; + const AxisSpec axisIsoEnergy{100, 0, 1.0, "E_{iso}"}; + const AxisSpec axisIsoEnergyZele{100, 0, 1.0, "E_{iso,ele}"}; + const AxisSpec axisIsoEnergyZpos{100, 0, 1.0, "E_{iso,pos}"}; + const AxisSpec axisIsoMomentum{100, 0, 10.0, "Isolation momentum(GeV/C)"}; + const AxisSpec axisIsoMomentumZele{100, 0, 10.0, "p_{iso,ele}"}; + const AxisSpec axisIsoMomentumZpos{100, 0, 10.0, "p_{iso,pos}"}; + const AxisSpec axisIsoTrack{25, -0.5, 24.5, "Isolation Track"}; + const AxisSpec axisIsoTrackZele{25, -0.5, 24.5, "N_{isotrk,ele}"}; + const AxisSpec axisIsoTrackZpos{25, -0.5, 24.5, "N_{isotrk,pos}"}; + const AxisSpec axisInvMassZgamma{150, 0, 150, "M_{ee} (GeV/c^{2})"}; + const AxisSpec axisInvMassZ{130, 20, 150, "M_{ee} (GeV/c^{2})"}; const AxisSpec axisTrigger{3, -0.5, 2.5, "Trigger status of zorro"}; const AxisSpec axisDPhiZh{64, -o2::constants::math::PIHalf, 3 * o2::constants::math::PIHalf, "#Delta#phi(Z-h)"}; const AxisSpec axisPtHadron{50, 0, 50, "p_{T,hadron} (GeV/c)"}; const AxisSpec axisPtZ{150, 0, 150, "p_{T,Z} (GeV/c)"}; const AxisSpec axisSign{2, -2, 2, "charge sign"}; - const AxisSpec axisCentrality{10, 0, 100, "Centrality (%)"}; + const AxisSpec axisCentrality{centralityBins}; const AxisSpec axisPtRatio{200, 0, 2.0, "pt ratio for h and Z"}; // create registrygrams @@ -259,14 +274,14 @@ struct HfTaskElectronWeakBoson { registry.add("hEopNsigTPC", "Eop vs. Nsigma", kTH2F, {{axisNsigma}, {axisEop}}); registry.add("hEMCtime", "EMC timing", kTH1F, {axisEMCtime}); registry.add("hIsolationEnergy", "Isolation Energy", kTH2F, {{axisE}, {axisIsoEnergy}}); - registry.add("hIsolationTrack", "Isolation Track", kTH2F, {{axisE}, {axisIsoTrack}}); - registry.add("hInvMassZee", "invariant mass for Z ULS pair", HistType::kTHnSparseF, {axisSign, axisPt, axisInvMassZ}); - registry.add("hKfInvMassZee", "invariant mass for Z ULS pair KFp", HistType::kTHnSparseF, {axisSign, axisPt, axisInvMassZ}); + registry.add("hInvMassZee", "invariant mass for Z ULS pair", HistType::kTHnSparseF, {axisCentrality, axisSign, axisPt, axisInvMassZgamma}); + registry.add("hKfInvMassZee", "invariant mass for Z ULS pair KFp", HistType::kTHnSparseF, {axisCentrality, axisSign, axisPt, axisInvMassZgamma}); + registry.add("hInvMassZeeQA", "QA for invariant mass for Z", HistType::kTHnSparseF, {axisInvMassZ, axisPtZele, axisPtZpos, axisEopZele, axisEopZpos, axisIsoEnergyZele, axisIsoEnergyZpos, axisIsoMomentumZele, axisIsoMomentumZpos, axisIsoTrackZele, axisIsoTrackZpos}); registry.add("hTHnElectrons", "electron info", HistType::kTHnSparseF, {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack, axisEta, axisDedx}); registry.add("hTHnTrMatch", "Track EMC Match", HistType::kTHnSparseF, {axisPt, axisdPhi, axisdEta}); // Z-hadron correlation histograms - registry.add("hZHadronDphi", "Z-hadron #Delta#phi correlation", HistType::kTHnSparseF, {axisSign, axisPtZ, axisDPhiZh, axisPtRatio, axisPtHadron}); + registry.add("hZHadronDphi", "Z-hadron #Delta#phi correlation", HistType::kTHnSparseF, {axisCentrality, axisSign, axisPtZ, axisDPhiZh, axisPtRatio, axisPtHadron}); registry.add("hZptSpectrum", "Z boson p_{T} spectrum", kTH2F, {{axisSign}, {axisPtZ}}); // hisotgram for EMCal trigger @@ -306,12 +321,15 @@ struct HfTaskElectronWeakBoson { return (isoEnergy); } - int getIsolatedTrack(double etaEle, - double phiEle, - float ptEle, - TrackEle const& tracks) + std::pair getIsolatedTrack(double etaEle, + double phiEle, + float pEle, + TrackEle const& tracks) { int trackCount = 0; + double isoMomentum = 10; + double pSum = 0.0; + // LOG(info) << "track p = " << pEle; for (const auto& track : tracks) { @@ -323,16 +341,22 @@ struct HfTaskElectronWeakBoson { if (deltaR < rIsolation) { trackCount++; + pSum += track.p(); } } - registry.fill(HIST("hIsolationTrack"), ptEle, trackCount); + // LOG(info) << "momSun = " << pSum; + if (pSum > 0) { + isoMomentum = pSum / pEle - 1.0; + } - return (trackCount); + // LOG(info) << "isop = " << isoMomentum; + return std::make_pair(trackCount - 1, isoMomentum); } void recoMassZee(KFParticle kfpIsoEle, int charge, + float centrality, TrackEle const& tracks) { // LOG(info) << "Invarimass cal by KF particle "; @@ -362,7 +386,7 @@ struct HfTaskElectronWeakBoson { auto child2 = RecoDecayPtEtaPhi::pVector(kfpAssEle.GetPt() * correctionPtElectron, kfpAssEle.GetEta(), kfpAssEle.GetPhi()); double invMassEE = RecoDecay::m(std::array{child1, child2}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); - registry.fill(HIST("hInvMassZee"), track.sign() * charge, kfpIsoEle.GetPt(), invMassEE); + registry.fill(HIST("hInvMassZee"), centrality, track.sign() * charge, kfpIsoEle.GetPt(), invMassEE); // reco by KFparticle const KFParticle* electronPairs[2] = {&kfpIsoEle, &kfpAssEle}; @@ -382,7 +406,7 @@ struct HfTaskElectronWeakBoson { } float massZee, massZeeErr; zeeKF.GetMass(massZee, massZeeErr); - registry.fill(HIST("hKfInvMassZee"), track.sign() * charge, kfpIsoEle.GetPt(), massZee); + registry.fill(HIST("hKfInvMassZee"), centrality, track.sign() * charge, kfpIsoEle.GetPt(), massZee); // LOG(info) << "Invarimass cal by KF particle mass = " << massZee; // LOG(info) << "Invarimass cal by RecoDecay = " << invMassEE; reconstructedZ.emplace_back( @@ -448,6 +472,7 @@ struct HfTaskElectronWeakBoson { } // initialze for inclusive-electron selectedElectronsIso.clear(); + selectedPositronsIso.clear(); selectedElectronsAss.clear(); reconstructedZ.clear(); @@ -460,8 +485,9 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hZvtx"), collision.posZ()); // Calculate centrality + float centrality = 1.0; if (enableCentralityAnalysis) { - float centrality = o2::hf_centrality::getCentralityColl(collision, centralityEstimator); + centrality = o2::hf_centrality::getCentralityColl(collision, centralityEstimator); // LOG(info) << centrality; if (centrality < centralityMin || centrality > centralityMax) { return; @@ -502,38 +528,46 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hPt"), track.pt()); registry.fill(HIST("hTPCNsigma"), track.p(), track.tpcNSigmaEl()); - float energyTrk = 0.0; + float eop = 0.0; + float isoEnergy = 1.0; + // track isolation + auto [trackCount, isoMomentum] = getIsolatedTrack(track.eta(), track.phi(), track.p(), tracks); + // LOG(info) << "isoMomentum = " << isoMomentum; if (track.pt() > ptAssMin) { selectedElectronsAss.emplace_back( track.pt(), track.eta(), track.phi(), - energyTrk, - track.sign()); + eop, + isoEnergy, + isoMomentum, + trackCount); } if (track.pt() < ptMin) { continue; } - // track - match - // continue; - if (track.phi() < phiEmcMin || track.phi() > phiEmcMax) - continue; - if (std::abs(track.eta()) > etaEmcMax) - continue; + // LOG(info) << "tr phi, eta = " << track.phi() << " ; " << track.eta(); + // EMC acc + bool isEMCacceptance = true; + if (track.phi() < phiEmcMin || track.phi() > phiEmcMax) { + isEMCacceptance = false; + } + if (std::abs(track.eta()) > etaEmcMax) { + isEMCacceptance = false; + } + // LOG(info) << "EMC acc = " << isEMCacceptance; auto tracksofcluster = matchedtracks.sliceBy(perClusterMatchedTracks, track.globalIndex()); - // LOGF(info, "Number of matched track: %d", tracksofcluster.size()); - double rMin = 999.9; double dPhiMin = 999.9; double dEtaMin = 999.9; bool isIsolated = false; bool isIsolatedTr = false; - if (tracksofcluster.size()) { + if (tracksofcluster.size() && isEMCacceptance) { int nMatch = 0; for (const auto& match : tracksofcluster) { if (match.emcalcluster_as().time() < timeEmcMin || match.emcalcluster_as().time() > timeEmcMax) @@ -557,6 +591,7 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hMatchEta"), etaEmc, match.track_as().trackEtaEmcal()); double r = RecoDecay::sqrtSumOfSquares(dPhi, dEta); + // LOG(info) << "r match = " << r; if (r < rMin) { rMin = r; dPhiMin = dPhi; @@ -574,11 +609,10 @@ struct HfTaskElectronWeakBoson { const auto& cluster = match.emcalcluster_as(); - double eop = energyEmc / match.track_as().p(); + eop = energyEmc / match.track_as().p(); + // LOG(info) << "eop = " << eop; - double isoEnergy = getIsolatedCluster(cluster, emcClusters); - - int trackCount = getIsolatedTrack(track.eta(), track.phi(), track.pt(), tracks) - 1; + isoEnergy = getIsolatedCluster(cluster, emcClusters); if (match.track_as().pt() > ptTHnThresh && isTHnElectron) { registry.fill(HIST("hTHnElectrons"), match.track_as().pt(), match.track_as().tpcNSigmaEl(), m02Emc, eop, isoEnergy, trackCount, track.eta(), track.tpcSignal()); @@ -606,29 +640,44 @@ struct HfTaskElectronWeakBoson { } KFPTrack kfpTrackIsoEle = createKFPTrackFromTrack(match.track_as()); KFParticle kfpIsoEle(kfpTrackIsoEle, pdgIso); - recoMassZee(kfpIsoEle, match.track_as().sign(), tracks); - - selectedElectronsIso.emplace_back( - match.track_as().pt(), - match.track_as().eta(), - match.track_as().phi(), - energyEmc, - match.track_as().sign()); - } - } + recoMassZee(kfpIsoEle, match.track_as().sign(), centrality, tracks); + + } // end of pt cut for e from Z + } // end if isolation cut if (isIsolatedTr) { registry.fill(HIST("hEopIsolationTr"), match.track_as().pt(), eop); } - } - } + } // end of PID cut + } // end of nmatch == 0 nMatch++; - } - } + } // end of cluster match + } // end of cluster if (rMin < rMatchMax) { // LOG(info) << "R mim = " << rMin; registry.fill(HIST("hTrMatch_mim"), dPhiMin, dEtaMin); } + if (enableZeeRecoQA && track.pt() > ptZeeMin) { + if (track.sign() < 0) { + selectedElectronsIso.emplace_back( + track.pt(), + track.eta(), + track.phi(), + eop, + isoEnergy, + isoMomentum, + trackCount); + } else { + selectedPositronsIso.emplace_back( + track.pt(), + track.eta(), + track.phi(), + eop, + isoEnergy, + isoMomentum, + trackCount); + } + } } // end of track loop // Z-hadron @@ -649,10 +698,23 @@ struct HfTaskElectronWeakBoson { // calculate Z-h correlation double deltaPhi = RecoDecay::constrainAngle(trackAss.phi - zBoson.phi, -o2::constants::math::PIHalf); double ptRatio = trackAss.pt / zBoson.pt; - registry.fill(HIST("hZHadronDphi"), zBoson.charge, zBoson.pt, deltaPhi, ptRatio, trackAss.pt); + registry.fill(HIST("hZHadronDphi"), centrality, zBoson.charge, zBoson.pt, deltaPhi, ptRatio, trackAss.pt); } } } // end of Z-hadron correlation + // Z->ee QA + if (enableZeeRecoQA) { + if (selectedElectronsIso.size() > 0 && selectedPositronsIso.size() > 0) { + for (const auto& trackEle : selectedElectronsIso) { + for (const auto& trackPos : selectedPositronsIso) { + auto child1 = RecoDecayPtEtaPhi::pVector(trackEle.pt, trackEle.eta, trackEle.phi); + auto child2 = RecoDecayPtEtaPhi::pVector(trackPos.pt, trackPos.eta, trackPos.phi); + double invMass = RecoDecay::m(std::array{child1, child2}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); + registry.fill(HIST("hInvMassZeeQA"), invMass, trackEle.pt, trackPos.pt, trackEle.eop, trackPos.eop, trackEle.energyIso, trackPos.energyIso, trackEle.momIso, trackPos.momIso, trackEle.ntrackIso, trackPos.ntrackIso); + } + } + } + } // end of Z->ee QA } }; diff --git a/PWGHF/HFL/Tasks/taskSingleElectron.cxx b/PWGHF/HFL/Tasks/taskSingleElectron.cxx index 12bf351c84d..a19b8c79cb8 100644 --- a/PWGHF/HFL/Tasks/taskSingleElectron.cxx +++ b/PWGHF/HFL/Tasks/taskSingleElectron.cxx @@ -89,6 +89,7 @@ struct HfTaskSingleElectron { Configurable tpcNSigmaMin{"tpcNSigmaMin", -1., "min of tpc nsigma"}; Configurable tpcNSigmaMax{"tpcNSigmaMax", 3., "max of tpc nsigma"}; + Configurable nBinsP{"nBinsP", 1500, "number of bins of particle momentum"}; Configurable nBinsPt{"nBinsPt", 100, "N bins in pT histo"}; // SliceCache @@ -112,6 +113,7 @@ struct HfTaskSingleElectron { const AxisSpec axisNCont{100, 0., 100., "nCont"}; const AxisSpec axisPosZ{600, -30., 30., "Z_{pos}"}; const AxisSpec axisEta{30, -1.5, +1.5, "#eta"}; + const AxisSpec axisP{nBinsP, 0., 15., "p_{T}"}; const AxisSpec axisPt{nBinsPt, 0., 15., "p_{T}"}; const AxisSpec axisNsig{800, -20., 20.}; const AxisSpec axisTrackIp{4000, -0.2, 0.2, "dca"}; @@ -139,7 +141,9 @@ struct HfTaskSingleElectron { // pid histos.add("tofNSigPt", "", kTH2D, {{axisPtEl}, {axisNsig}}); histos.add("tofNSigPtQA", "", kTH2D, {{axisPtEl}, {axisNsig}}); + histos.add("tpcNSigP", "", kTH2D, {{axisP}, {axisNsig}}); histos.add("tpcNSigPt", "", kTH2D, {{axisPtEl}, {axisNsig}}); + histos.add("tpcNSigPAfterTofCut", "", kTH2D, {{axisP}, {axisNsig}}); histos.add("tpcNSigPtAfterTofCut", "", kTH2D, {{axisPtEl}, {axisNsig}}); histos.add("tpcNSigPtQA", "", kTH2D, {{axisPtEl}, {axisNsig}}); @@ -430,12 +434,14 @@ struct HfTaskSingleElectron { histos.fill(HIST("dcaZTrack"), track.dcaZ()); histos.fill(HIST("tofNSigPt"), track.pt(), track.tofNSigmaEl()); + histos.fill(HIST("tpcNSigP"), track.p(), track.tpcNSigmaEl()); histos.fill(HIST("tpcNSigPt"), track.pt(), track.tpcNSigmaEl()); if (std::abs(track.tofNSigmaEl()) > tofNSigmaMax) { continue; } histos.fill(HIST("tofNSigPtQA"), track.pt(), track.tofNSigmaEl()); + histos.fill(HIST("tpcNSigPAfterTofCut"), track.p(), track.tpcNSigmaEl()); histos.fill(HIST("tpcNSigPtAfterTofCut"), track.pt(), track.tpcNSigmaEl()); if (track.tpcNSigmaEl() < tpcNSigmaMin || track.tpcNSigmaEl() > tpcNSigmaMax) { diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index bd3cb47b28f..b5d0c2258f9 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -97,38 +97,24 @@ struct HfCandidateSelectorDstarToD0Pi { Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; - // ML inference D0 - Configurable applyMlD0Daug{"applyMlD0Daug", false, "Flag to apply ML selections on D0 daughter"}; - Configurable> binsPtMlD0Daug{"binsPtMlD0Daug", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application on D0 daughter"}; - Configurable> cutDirMlD0Daug{"cutDirMlD0Daug", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold on D0 daughter"}; - Configurable> cutsMlD0Daug{"cutsMlD0Daug", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin on D0 daughter"}; - Configurable nClassesMlD0Daug{"nClassesMlD0Daug", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model on D0 daughter"}; - Configurable> namesInputFeaturesD0Daug{"namesInputFeaturesD0Daug", std::vector{"feature1", "feature2"}, "Names of ML model input features on D0 daughter"}; + Configurable isTriggerBDT{"isTriggerBDT", false, "Flag to enable / disable features for software trigger BDTs"}; // CCDB configuration Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{""}, "Paths of models on CCDB"}; - Configurable> modelPathsCCDBD0Daug{"modelPathsCCDBD0Daug", std::vector{""}, "Paths of models on CCDB for D0 daughter"}; Configurable> onnxFileNames{"onnxFileNames", std::vector{"Model.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; - Configurable> onnxFileNamesD0Daug{"onnxFileNamesD0Daug", std::vector{"Model.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path) for D0 daughter"}; Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - // PDG mass for kaon, pion and D0 - double massD0, massPi, massK; - HfHelper hfHelper; o2::analysis::HfMlResponseDstarToD0Pi hfMlResponse; - o2::analysis::HfMlResponseDstarToD0Pi hfMlResponseD0Daughter; std::vector outputMlDstarToD0Pi = {}; - std::vector outputMlD0ToKPi = {}; o2::ccdb::CcdbApi ccdbApi; TrackSelectorPi selectorPion; TrackSelectorKa selectorKaon; using TracksSel = soa::Join; - // using TracksSel = soa::Join; using HfFullDstarCandidate = soa::Join; AxisSpec axisBdtScore{100, 0.f, 1.f}; @@ -139,9 +125,6 @@ struct HfCandidateSelectorDstarToD0Pi { void init(InitContext&) { - massPi = MassPiPlus; - massK = MassKPlus; - massD0 = MassD0; selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); selectorPion.setRangeNSigmaTpc(-nSigmaTpcMax, nSigmaTpcMax); @@ -183,18 +166,6 @@ struct HfCandidateSelectorDstarToD0Pi { hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); hfMlResponse.init(); } - - if (applyMlD0Daug) { - hfMlResponseD0Daughter.configure(binsPtMlD0Daug, cutsMlD0Daug, cutDirMlD0Daug, nClassesMlD0Daug); - if (loadModelsFromCCDB) { - ccdbApi.init(ccdbUrl); - hfMlResponseD0Daughter.setModelPathsCCDB(onnxFileNamesD0Daug, ccdbApi, modelPathsCCDBD0Daug, timestampCCDB); - } else { - hfMlResponseD0Daughter.setModelPathsLocal(onnxFileNamesD0Daug); - } - hfMlResponseD0Daughter.cacheInputFeaturesIndices(namesInputFeaturesD0Daug); - hfMlResponseD0Daughter.init(); - } } /// Conjugate-independent topological cuts on D0 @@ -258,14 +229,6 @@ struct HfCandidateSelectorDstarToD0Pi { return false; } - if (applyMlD0Daug) { - outputMlD0ToKPi.clear(); - std::vector inputFeaturesD0 = hfMlResponseD0Daughter.getInputFeaturesTrigger(candidate); - bool isSelectedMlD0 = hfMlResponseD0Daughter.isSelectedMl(inputFeaturesD0, candpT, outputMlD0ToKPi); - if (!isSelectedMlD0) { - return false; - } - } return true; } @@ -323,10 +286,10 @@ struct HfCandidateSelectorDstarToD0Pi { if (prongSoftPi.sign() > 0.) { // Selection of D*+ mInvDstar = candidate.invMassDstar(); mInvD0 = candidate.invMassD0(); - if (std::abs(mInvD0 - massD0) > cutsD0->get(binPt, "m")) { + if (std::abs(mInvD0 - MassD0) > cutsD0->get(binPt, "m")) { return false; } - if (useTriggerMassCut && !isCandidateInMassRange(mInvD0, massD0, candidate.ptD0(), hfTriggerCuts)) { + if (useTriggerMassCut && !isCandidateInMassRange(mInvD0, MassD0, candidate.ptD0(), hfTriggerCuts)) { return false; } // cut on daughter pT @@ -351,10 +314,10 @@ struct HfCandidateSelectorDstarToD0Pi { } else if (prongSoftPi.sign() < 0.) { // Selection of D*- mInvAntiDstar = candidate.invMassAntiDstar(); mInvD0Bar = candidate.invMassD0Bar(); - if (std::abs(mInvD0Bar - massD0) > cutsD0->get(binPt, "m")) { + if (std::abs(mInvD0Bar - MassD0) > cutsD0->get(binPt, "m")) { return false; } - if (useTriggerMassCut && !isCandidateInMassRange(mInvD0Bar, massD0, candidate.ptD0(), hfTriggerCuts)) { + if (useTriggerMassCut && !isCandidateInMassRange(mInvD0Bar, MassD0, candidate.ptD0(), hfTriggerCuts)) { return false; } // cut on daughter pT @@ -379,11 +342,11 @@ struct HfCandidateSelectorDstarToD0Pi { // in case only sideband candidates have to be stored, additional invariant-mass cut if (keepOnlySidebandCandidates && prongSoftPi.sign() > 0.) { - if (std::abs((mInvDstar - mInvD0) - massPi) < distanceFromDeltaMassForSidebands) { + if (std::abs((mInvDstar - mInvD0) - MassPiPlus) < distanceFromDeltaMassForSidebands) { return false; } } else if (keepOnlySidebandCandidates && prongSoftPi.sign() < 0.) { - if (std::abs((mInvAntiDstar - mInvD0Bar) - massPi) < distanceFromDeltaMassForSidebands) { + if (std::abs((mInvAntiDstar - mInvD0Bar) - MassPiPlus) < distanceFromDeltaMassForSidebands) { return false; } } @@ -499,8 +462,7 @@ struct HfCandidateSelectorDstarToD0Pi { if (applyMl) { // ML selections bool isSelectedMlDstar = false; - - std::vector inputFeatures = hfMlResponse.getInputFeatures(candDstar); + std::vector inputFeatures = hfMlResponse.getInputFeatures(candDstar, !isTriggerBDT); isSelectedMlDstar = hfMlResponse.isSelectedMl(inputFeatures, ptCand, outputMlDstarToD0Pi); hfMlDstarCandidate(outputMlDstarToD0Pi); diff --git a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx index a4a026a005b..d91ab2f718e 100644 --- a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx +++ b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx @@ -54,6 +54,7 @@ using namespace o2::framework; struct HfCandidateSelectorLcToK0sP { Produces hfSelLcToK0sPCandidate; + Produces hfMlLcToK0sPCandidate; Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; @@ -95,6 +96,7 @@ struct HfCandidateSelectorLcToK0sP { TrackSelectorPr selectorProtonHighP; o2::analysis::HfMlResponseLcToK0sP hfMlResponse; + std::vector outputMl = {}; o2::ccdb::CcdbApi ccdbApi; @@ -239,12 +241,11 @@ struct HfCandidateSelectorLcToK0sP { } template - bool selectionMl(const T& hfCandCascade, const U& bach) + bool selectionMl(const T& hfCandCascade, const U& bach, std::vector& outputMl) { auto ptCand = hfCandCascade.pt(); std::vector inputFeatures = hfMlResponse.getInputFeatures(hfCandCascade, bach); - std::vector outputMl = {}; bool isSelectedMl = hfMlResponse.isSelectedMl(inputFeatures, ptCand, outputMl); @@ -265,26 +266,37 @@ struct HfCandidateSelectorLcToK0sP { const auto& bach = candidate.prong0_as(); // bachelor track statusLc = 0; + outputMl.clear(); // implement filter bit 4 cut - should be done before this task at the track selection level // need to add special cuts (additional cuts on decay length and d0 norm) if (!selectionTopol(candidate)) { hfSelLcToK0sPCandidate(statusLc); + if (applyMl) { + hfMlLcToK0sPCandidate(outputMl); + } continue; } if (!selectionStandardPID(bach)) { hfSelLcToK0sPCandidate(statusLc); + if (applyMl) { + hfMlLcToK0sPCandidate(outputMl); + } continue; } - if (applyMl && !selectionMl(candidate, bach)) { - hfSelLcToK0sPCandidate(statusLc); - continue; + if (applyMl) { + bool isSelectedMlLcToK0sP = selectionMl(candidate, bach, outputMl); + hfMlLcToK0sPCandidate(outputMl); + + if (!isSelectedMlLcToK0sP) { + hfSelLcToK0sPCandidate(statusLc); + continue; + } } statusLc = 1; - hfSelLcToK0sPCandidate(statusLc); } } @@ -299,24 +311,35 @@ struct HfCandidateSelectorLcToK0sP { const auto& bach = candidate.prong0_as(); // bachelor track statusLc = 0; + outputMl.clear(); if (!selectionTopol(candidate)) { hfSelLcToK0sPCandidate(statusLc); + if (applyMl) { + hfMlLcToK0sPCandidate(outputMl); + } continue; } if (!selectionBayesPID(bach)) { hfSelLcToK0sPCandidate(statusLc); + if (applyMl) { + hfMlLcToK0sPCandidate(outputMl); + } continue; } - if (applyMl && !selectionMl(candidate, bach)) { - hfSelLcToK0sPCandidate(statusLc); - continue; + if (applyMl) { + bool isSelectedMlLcToK0sP = selectionMl(candidate, bach, outputMl); + hfMlLcToK0sPCandidate(outputMl); + + if (!isSelectedMlLcToK0sP) { + hfSelLcToK0sPCandidate(statusLc); + continue; + } } statusLc = 1; - hfSelLcToK0sPCandidate(statusLc); } } diff --git a/PWGHF/TableProducer/treeCreatorLcToK0sP.cxx b/PWGHF/TableProducer/treeCreatorLcToK0sP.cxx index 0012108a45c..1e2b2484c13 100644 --- a/PWGHF/TableProducer/treeCreatorLcToK0sP.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToK0sP.cxx @@ -33,8 +33,10 @@ #include #include +#include #include #include +#include using namespace o2; using namespace o2::framework; @@ -68,8 +70,8 @@ DECLARE_SOA_COLUMN(DecayLength, decayLength, float); DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); -DECLARE_SOA_COLUMN(CPA, cpa, float); -DECLARE_SOA_COLUMN(CPAXY, cpaXY, float); +DECLARE_SOA_COLUMN(Cpa, cpa, float); +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); DECLARE_SOA_COLUMN(Ct, ct, float); DECLARE_SOA_COLUMN(PtV0Pos, ptV0Pos, float); DECLARE_SOA_COLUMN(PtV0Neg, ptV0Neg, float); @@ -84,6 +86,9 @@ DECLARE_SOA_COLUMN(V0CtLambda, v0CtLambda, float); DECLARE_SOA_COLUMN(FlagMc, flagMc, int8_t); DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); +DECLARE_SOA_COLUMN(MlScoreFirstClass, mlScoreFirstClass, float); +DECLARE_SOA_COLUMN(MlScoreSecondClass, mlScoreSecondClass, float); +DECLARE_SOA_COLUMN(MlScoreThirdClass, mlScoreThirdClass, float); // Events DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int); DECLARE_SOA_COLUMN(RunNumber, runNumber, int); @@ -118,15 +123,18 @@ DECLARE_SOA_TABLE(HfCandCascLites, "AOD", "HFCANDCASCLITE", full::NSigmaTOFPr0, full::M, full::Pt, - full::CPA, - full::CPAXY, + full::Cpa, + full::CpaXY, full::Ct, full::Eta, full::Phi, full::Y, full::E, full::FlagMc, - full::OriginMcRec); + full::OriginMcRec, + full::MlScoreFirstClass, + full::MlScoreSecondClass, + full::MlScoreThirdClass); DECLARE_SOA_TABLE(HfCandCascFulls, "AOD", "HFCANDCASCFULL", collision::BCId, @@ -188,15 +196,18 @@ DECLARE_SOA_TABLE(HfCandCascFulls, "AOD", "HFCANDCASCFULL", full::M, full::Pt, full::P, - full::CPA, - full::CPAXY, + full::Cpa, + full::CpaXY, full::Ct, full::Eta, full::Phi, full::Y, full::E, full::FlagMc, - full::OriginMcRec); + full::OriginMcRec, + full::MlScoreFirstClass, + full::MlScoreSecondClass, + full::MlScoreThirdClass); DECLARE_SOA_TABLE(HfCandCascFullEs, "AOD", "HFCANDCASCFULLE", collision::BCId, @@ -228,23 +239,56 @@ struct HfTreeCreatorLcToK0sP { Configurable ptMaxForDownSample{"ptMaxForDownSample", 24., "Maximum pt for the application of the downsampling factor"}; Configurable fillOnlySignal{"fillOnlySignal", false, "Flag to fill derived tables with signal for ML trainings"}; Configurable fillOnlyBackground{"fillOnlyBackground", false, "Flag to fill derived tables with background for ML trainings"}; + Configurable applyMl{"applyMl", false, "Whether ML was used in candidateSelectorLc"}; + + constexpr static float UndefValueFloat = -999.f; HfHelper hfHelper; - Filter filterSelectCandidates = aod::hf_sel_candidate_lc_to_k0s_p::isSelLcToK0sP >= 1; using TracksWPid = soa::Join; using SelectedCandidatesMc = soa::Filtered>; - - Partition recSig = nabs(aod::hf_cand_casc::flagMcMatchRec) != int8_t(0); - Partition recBkg = nabs(aod::hf_cand_casc::flagMcMatchRec) == int8_t(0); + Filter filterSelectCandidates = aod::hf_sel_candidate_lc_to_k0s_p::isSelLcToK0sP >= 1; void init(InitContext const&) { } + /// \brief function to get ML score values for the current candidate and assign them to input parameters + /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate + /// \param mlScoreFirstClass ML score for belonging to the first class + /// \param mlScoreSecondClass ML score for belonging to the second class + /// \param mlScoreThirdClass ML score for belonging to the third class + void assignMlScores(aod::HfMlLcToK0sP::iterator const& candidateMlScore, float& mlScoreFirstClass, float& mlScoreSecondClass, float& mlScoreThirdClass) + { + std::vector mlScores; + std::copy(candidateMlScore.mlProbLcToK0sP().begin(), candidateMlScore.mlProbLcToK0sP().end(), std::back_inserter(mlScores)); + + constexpr int IndexFirstClass{0}; + constexpr int IndexSecondClass{1}; + constexpr int IndexThirdClass{2}; + if (mlScores.size() == 0) { + return; // when candidateSelectorLcK0sP rejects a candidate by "usual", non-ML cut, the ml score vector remains empty + } + mlScoreFirstClass = mlScores.at(IndexFirstClass); + mlScoreSecondClass = mlScores.at(IndexSecondClass); + if (mlScores.size() > IndexThirdClass) { + mlScoreThirdClass = mlScores.at(IndexThirdClass); + } + } + template - void fillCandidate(const T& candidate, const U& bach, int8_t flagMc, int8_t originMcRec) + void fillCandidate(const T& candidate, const U& bach, int8_t flagMc, int8_t originMcRec, aod::HfMlLcToK0sP::iterator const& candidateMlScore) { + + float mlScoreFirstClass{UndefValueFloat}; + float mlScoreSecondClass{UndefValueFloat}; + float mlScoreThirdClass{UndefValueFloat}; + + if (applyMl) { + assignMlScores(candidateMlScore, mlScoreFirstClass, mlScoreSecondClass, mlScoreThirdClass); + } + if (fillCandidateLiteTable) { rowCandidateLite( candidate.chi2PCA(), @@ -283,7 +327,10 @@ struct HfTreeCreatorLcToK0sP { hfHelper.yLc(candidate), hfHelper.eLc(candidate), flagMc, - originMcRec); + originMcRec, + mlScoreFirstClass, + mlScoreSecondClass, + mlScoreThirdClass); } else { rowCandidateFull( bach.collision().bcId(), @@ -353,7 +400,10 @@ struct HfTreeCreatorLcToK0sP { hfHelper.yLc(candidate), hfHelper.eLc(candidate), flagMc, - originMcRec); + originMcRec, + mlScoreFirstClass, + mlScoreSecondClass, + mlScoreThirdClass); } } template @@ -370,52 +420,41 @@ struct HfTreeCreatorLcToK0sP { void processMc(aod::Collisions const& collisions, aod::McCollisions const&, SelectedCandidatesMc const& candidates, + aod::HfMlLcToK0sP const& candidateMlScores, soa::Join const& particles, TracksWPid const&) { + if (applyMl && candidateMlScores.size() == 0) { + LOG(fatal) << "ML enabled but table with the ML scores is empty! Please check your configurables."; + return; + } + // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); for (const auto& collision : collisions) { fillEvent(collision); } - if (fillOnlySignal) { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(recSig.size()); - } else { - rowCandidateFull.reserve(recSig.size()); - } - for (const auto& candidate : recSig) { - auto bach = candidate.prong0_as(); // bachelor - fillCandidate(candidate, bach, candidate.flagMcMatchRec(), candidate.originMcRec()); - } - } else if (fillOnlyBackground) { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(recBkg.size()); - } else { - rowCandidateFull.reserve(recBkg.size()); - } - for (const auto& candidate : recBkg) { - if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); - if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { - continue; - } - } - auto bach = candidate.prong0_as(); // bachelor - fillCandidate(candidate, bach, candidate.flagMcMatchRec(), candidate.originMcRec()); - } + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(candidates.size()); } else { - // Filling candidate properties - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); + rowCandidateFull.reserve(candidates.size()); + } + + int iCand{0}; + for (const auto& candidate : candidates) { + auto candidateMlScore = candidateMlScores.rawIteratorAt(iCand); + ++iCand; + auto bach = candidate.prong0_as(); // bachelor + const int flag = candidate.flagMcMatchRec(); + + if (fillOnlySignal && flag != 0) { + fillCandidate(candidate, bach, candidate.flagMcMatchRec(), candidate.originMcRec(), candidateMlScore); + } else if (fillOnlyBackground && flag == 0) { + fillCandidate(candidate, bach, candidate.flagMcMatchRec(), candidate.originMcRec(), candidateMlScore); } else { - rowCandidateFull.reserve(candidates.size()); - } - for (const auto& candidate : candidates) { - auto bach = candidate.prong0_as(); // bachelor - fillCandidate(candidate, bach, candidate.flagMcMatchRec(), candidate.originMcRec()); + fillCandidate(candidate, bach, candidate.flagMcMatchRec(), candidate.originMcRec(), candidateMlScore); } } @@ -439,9 +478,15 @@ struct HfTreeCreatorLcToK0sP { void processData(aod::Collisions const& collisions, soa::Join const& candidates, + aod::HfMlLcToK0sP const& candidateMlScores, TracksWPid const&) { + if (applyMl && candidateMlScores.size() == 0) { + LOG(fatal) << "ML enabled but table with the ML scores is empty! Please check your configurables."; + return; + } + // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); for (const auto& collision : collisions) { @@ -454,11 +499,15 @@ struct HfTreeCreatorLcToK0sP { } else { rowCandidateFull.reserve(candidates.size()); } + + int iCand{0}; for (const auto& candidate : candidates) { + auto candidateMlScore = candidateMlScores.rawIteratorAt(iCand); + ++iCand; auto bach = candidate.prong0_as(); // bachelor double pseudoRndm = bach.pt() * 1000. - static_cast(bach.pt() * 1000); if (candidate.isSelLcToK0sP() >= 1 && pseudoRndm < downSampleBkgFactor) { - fillCandidate(candidate, bach, 0, 0); + fillCandidate(candidate, bach, 0, 0, candidateMlScore); } } } diff --git a/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx b/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx index 4fb9c92235c..f102151596c 100644 --- a/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx @@ -211,7 +211,7 @@ DECLARE_SOA_TABLE(HfKfOmegacFulls, "AOD", "HFKFOMEGACFULL", full::MassV0Ndf, full::MassCascNdf, full::V0Chi2OverNdf, full::CascChi2OverNdf, full::OmegacChi2OverNdf, full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, full::CascRejectInvmass, - full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched, hf_track_index::HFflag); + full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched, hf_track_index::HFflag, collision::NumContrib); DECLARE_SOA_TABLE(HfKfOmegacLites, "AOD", "HFKFOMEGACLITE", full::NSigmaTPCPiFromOmegac, full::NSigmaTOFPiFromOmegac, full::NSigmaTPCKaFromCasc, full::NSigmaTOFKaFromCasc, @@ -225,7 +225,7 @@ DECLARE_SOA_TABLE(HfKfOmegacLites, "AOD", "HFKFOMEGACLITE", full::CosThetaStarPiFromOmegac, full::CtOmegac, full::EtaOmegac, full::V0Chi2OverNdf, full::CascChi2OverNdf, full::OmegacChi2OverNdf, full::CascRejectInvmass, - full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched, hf_track_index::HFflag); + full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched, hf_track_index::HFflag, collision::NumContrib); } // namespace o2::aod /// Writes the full information in an output TTree @@ -396,7 +396,8 @@ struct HfTreeCreatorOmegac0ToOmegaPi { flagMc, originMc, collisionMatched, - candidate.hfflag()); + candidate.hfflag(), + candidate.template collision_as().numContrib()); } } @@ -439,7 +440,8 @@ struct HfTreeCreatorOmegac0ToOmegaPi { flagMc, originMc, collisionMatched, - candidate.hfflag()); + candidate.hfflag(), + candidate.template collision_as().numContrib()); } } // fillKfCandidateLite end diff --git a/PWGHF/Tasks/taskMcValidation.cxx b/PWGHF/Tasks/taskMcValidation.cxx index 8cf7ea7d0ce..083b85d6255 100644 --- a/PWGHF/Tasks/taskMcValidation.cxx +++ b/PWGHF/Tasks/taskMcValidation.cxx @@ -89,6 +89,7 @@ enum DecayChannels { DzeroToKPi = 0, D2Star0ToDPlusPi, B0ToDminusPi, BplusToD0Pi, + BsToDsPi, LcToPKPi, LcToPiK0s, XiCplusToPKPi, @@ -100,31 +101,33 @@ enum DecayChannels { DzeroToKPi = 0, }; // always keep nChannels at the end static constexpr int nCharmMesonChannels = 10; // number of charm meson channels -static constexpr int nBeautyChannels = 2; // number of beauty hadron channels +static constexpr int nBeautyChannels = 3; // number of beauty hadron channels static constexpr int nCharmBaryonChannels = nChannels - nCharmMesonChannels - nBeautyChannels; // number of charm baryon channels static constexpr int nOriginTypes = 2; // number of origin types (prompt, non-prompt; only for charm hadrons) static constexpr std::array PDGArrayParticle = {o2::constants::physics::Pdg::kD0, o2::constants::physics::Pdg::kDStar, o2::constants::physics::Pdg::kDPlus, o2::constants::physics::Pdg::kDPlus, o2::constants::physics::Pdg::kDS, o2::constants::physics::Pdg::kDS, o2::constants::physics::Pdg::kDS1, o2::constants::physics::Pdg::kDS2Star, - o2::constants::physics::Pdg::kD10, o2::constants::physics::Pdg::kD2Star0, o2::constants::physics::Pdg::kB0, o2::constants::physics::Pdg::kBPlus, o2::constants::physics::Pdg::kLambdaCPlus, - o2::constants::physics::Pdg::kLambdaCPlus, o2::constants::physics::Pdg::kXiCPlus, o2::constants::physics::Pdg::kXiCPlus, o2::constants::physics::Pdg::kXiC0, + o2::constants::physics::Pdg::kD10, o2::constants::physics::Pdg::kD2Star0, + o2::constants::physics::Pdg::kB0, o2::constants::physics::Pdg::kBPlus, o2::constants::physics::Pdg::kBS, + o2::constants::physics::Pdg::kLambdaCPlus, o2::constants::physics::Pdg::kLambdaCPlus, + o2::constants::physics::Pdg::kXiCPlus, o2::constants::physics::Pdg::kXiCPlus, o2::constants::physics::Pdg::kXiC0, o2::constants::physics::Pdg::kOmegaC0, o2::constants::physics::Pdg::kOmegaC0}; -static constexpr std::array nDaughters = {2, 3, 3, 3, 3, 3, 5, 5, 4, 4, 4, 3, 3, 3, 3, 5, 4, 4, 4}; -static constexpr std::array maxDepthForSearch = {1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 2, 4, 3, 3, 3}; +static constexpr std::array nDaughters = {2, 3, 3, 3, 3, 3, 5, 5, 4, 4, 4, 3, 4, 3, 3, 3, 5, 4, 4, 4}; +static constexpr std::array maxDepthForSearch = {1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 2, 3, 2, 4, 3, 3, 3}; // keep coherent indexing with PDGArrayParticle // FIXME: look for a better solution -static constexpr std::array, nChannels> arrPDGFinal2Prong = {{{+kPiPlus, -kKPlus}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}; -static constexpr std::array, nChannels> arrPDGFinal3Prong = {{{}, {+kPiPlus, -kKPlus, +kPiPlus}, {+kPiPlus, -kKPlus, +kPiPlus}, {+kKPlus, -kKPlus, +kPiPlus}, {+kKPlus, -kKPlus, +kPiPlus}, {+kKPlus, -kKPlus, +kPiPlus}, {}, {}, {}, {}, {}, {-kPiPlus, +kKPlus, +kPiPlus}, {+kProton, -kKPlus, +kPiPlus}, {+kProton, -kPiPlus, +kPiPlus}, {+kProton, -kKPlus, +kPiPlus}, {}, {}, {}, {}}}; -static constexpr std::array, nChannels> arrPDGFinal4Prong = {{{}, {}, {}, {}, {}, {}, {}, {}, {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}, {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}, {-kPiPlus, +kKPlus, -kPiPlus, +kPiPlus}, {}, {}, {}, {}, {}, {+kPiPlus, -kPiPlus, -kPiPlus, +kProton}, {+kPiPlus, -kKPlus, -kPiPlus, +kProton}, {+kPiPlus, -kPiPlus, -kPiPlus, +kProton}}}; -static constexpr std::array, nChannels> arrPDGFinal5Prong = {{{}, {}, {}, {}, {}, {}, {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, {}, {}, {}, {}, {}, {}, {}, {+kPiPlus, +kPiPlus, -kPiPlus, -kPiPlus, +kProton}, {}, {}, {}}}; +static constexpr std::array, nChannels> arrPDGFinal2Prong = {{{+kPiPlus, -kKPlus}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}; +static constexpr std::array, nChannels> arrPDGFinal3Prong = {{{}, {+kPiPlus, -kKPlus, +kPiPlus}, {+kPiPlus, -kKPlus, +kPiPlus}, {+kKPlus, -kKPlus, +kPiPlus}, {+kKPlus, -kKPlus, +kPiPlus}, {+kKPlus, -kKPlus, +kPiPlus}, {}, {}, {}, {}, {}, {-kPiPlus, +kKPlus, +kPiPlus}, {}, {+kProton, -kKPlus, +kPiPlus}, {+kProton, -kPiPlus, +kPiPlus}, {+kProton, -kKPlus, +kPiPlus}, {}, {}, {}, {}}}; +static constexpr std::array, nChannels> arrPDGFinal4Prong = {{{}, {}, {}, {}, {}, {}, {}, {}, {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}, {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}, {-kPiPlus, +kKPlus, -kPiPlus, +kPiPlus}, {}, {-kKPlus, +kKPlus, -kPiPlus, +kPiPlus}, {}, {}, {}, {}, {+kPiPlus, -kPiPlus, -kPiPlus, +kProton}, {+kPiPlus, -kKPlus, -kPiPlus, +kProton}, {+kPiPlus, -kPiPlus, -kPiPlus, +kProton}}}; +static constexpr std::array, nChannels> arrPDGFinal5Prong = {{{}, {}, {}, {}, {}, {}, {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, {}, {}, {}, {}, {}, {}, {}, {}, {+kPiPlus, +kPiPlus, -kPiPlus, -kPiPlus, +kProton}, {}, {}, {}}}; static constexpr std::string_view labels[nChannels] = {"D^{0} #rightarrow K#pi", "D*^{+} #rightarrow D^{0}#pi", "D^{+} #rightarrow K#pi#pi", "D^{+} #rightarrow KK#pi", "D_{s}^{+} #rightarrow #Phi#pi #rightarrow KK#pi", "D_{s}^{+} #rightarrow #bar{K}^{*0}K #rightarrow KK#pi", "D_{s}1 #rightarrow D*^{+}K^{0}_{s}", "D_{s}2* #rightarrow D^{+}K^{0}_{s}", "D1^{0} #rightarrow D*^{+}#pi", "D2^{*} #rightarrow D^{+}#pi", - "B^{0} #rightarrow D^{-}#pi", "B^{+} #rightarrow D^{0}#pi", + "B^{0} #rightarrow D^{-}#pi", "B^{+} #rightarrow D^{0}#pi", "B_{s}^{+} #rightarrow D_{s}^{-}#pi", "#Lambda_{c}^{+} #rightarrow pK#pi", "#Lambda_{c}^{+} #rightarrow pK^{0}_{s}", "#Xi_{c}^{+} #rightarrow pK#pi", "#Xi_{c}^{+} #rightarrow #Xi#pi#pi", "#Xi_{c}^{0} #rightarrow #Xi#pi", "#Omega_{c}^{0} #rightarrow #Omega#pi", "#Omega_{c}^{0} #rightarrow #Xi#pi"}; -static constexpr std::string_view particleNames[nChannels] = {"DzeroToKPi", "DstarToDzeroPi", "DplusToPiKPi", "DplusToPhiPiToKKPi", "DsToPhiPiToKKPi", "DsToK0starKToKKPi", "Ds1ToDStarK0s", "Ds2StarToDPlusK0s", "D10ToDStarPi", "D2Star0ToDPlusPi", "B0ToDminusPi", "BplusToD0Pi", +static constexpr std::string_view particleNames[nChannels] = {"DzeroToKPi", "DstarToDzeroPi", "DplusToPiKPi", "DplusToPhiPiToKKPi", "DsToPhiPiToKKPi", "DsToK0starKToKKPi", "Ds1ToDStarK0s", "Ds2StarToDPlusK0s", "D10ToDStarPi", "D2Star0ToDPlusPi", "B0ToDminusPi", "BplusToD0Pi", "BsToDsPi", "LcToPKPi", "LcToPiK0s", "XiCplusToPKPi", "XiCplusToXiPiPi", "XiCzeroToXiPi", "OmegaCToOmegaPi", "OmegaCToXiPi"}; static constexpr std::string_view originNames[nOriginTypes] = {"Prompt", "NonPrompt"}; } // namespace @@ -417,6 +420,10 @@ struct HfTaskMcValidationGen { !RecoDecay::isMatchedMCGen(mcParticles, particle, PDGArrayParticle[iD], std::array{-o2::constants::physics::Pdg::kDPlus, +kPiPlus}, true)) { continue; } + if (iD == BsToDsPi && + !RecoDecay::isMatchedMCGen(mcParticles, particle, PDGArrayParticle[iD], std::array{-o2::constants::physics::Pdg::kDS, +kPiPlus}, true)) { + continue; + } } if (nDaughters[iD] == 5) { diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index 4af173070d5..f53b199d62a 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -150,7 +150,7 @@ void setEventRejectionLabels(Histo& hRejection, std::string const& softwareTrigg struct HfEventSelection : o2::framework::ConfigurableGroup { std::string prefix = "hfEvSel"; // JSON group name // event selection parameters (in chronological order of application) - o2::framework::Configurable centralityMin{"centralityMin", 0.f, "Minimum centrality"}; + o2::framework::Configurable centralityMin{"centralityMin", -10.f, "Minimum centrality (0 rejects gen. collisions with no reco. collision)"}; o2::framework::Configurable centralityMax{"centralityMax", 100.f, "Maximum centrality"}; o2::framework::Configurable useSel8Trigger{"useSel8Trigger", true, "Apply the sel8 event selection"}; o2::framework::Configurable triggerClass{"triggerClass", -1, "Trigger class different from sel8 (e.g. kINT7 for Run2) used only if useSel8Trigger is false"}; @@ -432,7 +432,7 @@ struct HfEventSelectionMc { bool useItsRofBorderCut{false}; // Apply the ITS RO frame border cut float zPvPosMin{-1000.f}; // Minimum PV posZ (cm) float zPvPosMax{1000.f}; // Maximum PV posZ (cm) - float centralityMin{0.f}; // Minimum centrality + float centralityMin{-10.f}; // Minimum centrality float centralityMax{100.f}; // Maximum centrality bool requireGoodRct{false}; // Apply RCT selection std::string rctLabel{""}; // RCT selection flag diff --git a/PWGJE/Core/JetTaggingUtilities.h b/PWGJE/Core/JetTaggingUtilities.h index 616929ac1ed..849580fb1c8 100644 --- a/PWGJE/Core/JetTaggingUtilities.h +++ b/PWGJE/Core/JetTaggingUtilities.h @@ -1070,7 +1070,7 @@ void analyzeJetTrackInfo4GNN(AnalysisJet const& analysisJet, AnyTracks const& /* auto origConstit = constituent.template track_as(); if (static_cast(tracksParams.size()) < nMaxConstit) { - tracksParams.emplace_back(std::vector{constituent.pt(), origConstit.phi(), constituent.eta(), static_cast(constituent.sign()), std::abs(constituent.dcaXY()) * sign, constituent.sigmadcaXY(), std::abs(constituent.dcaXYZ()) * sign, constituent.sigmadcaXYZ(), static_cast(origConstit.itsNCls()), static_cast(origConstit.tpcNClsFound()), static_cast(origConstit.tpcNClsCrossedRows()), origConstit.itsChi2NCl(), origConstit.tpcChi2NCl()}); + tracksParams.emplace_back(std::vector{constituent.pt(), origConstit.phi(), constituent.eta(), static_cast(constituent.sign()), std::abs(constituent.dcaXY()) * sign, constituent.sigmadcaXY(), std::abs(constituent.dcaZ()) * sign, constituent.sigmadcaZ(), static_cast(origConstit.itsNCls()), static_cast(origConstit.tpcNClsFound()), static_cast(origConstit.tpcNClsCrossedRows()), origConstit.itsChi2NCl(), origConstit.tpcChi2NCl()}); } else { // If there are more than nMaxConstit constituents in the jet, select only nMaxConstit constituents with the highest DCA_XY significance. size_t minIdx = 0; @@ -1079,7 +1079,7 @@ void analyzeJetTrackInfo4GNN(AnalysisJet const& analysisJet, AnyTracks const& /* minIdx = i; } if (std::abs(constituent.dcaXY()) * sign / constituent.sigmadcaXY() > tracksParams[minIdx][4] / tracksParams[minIdx][5]) - tracksParams[minIdx] = std::vector{constituent.pt(), origConstit.phi(), constituent.eta(), static_cast(constituent.sign()), std::abs(constituent.dcaXY()) * sign, constituent.sigmadcaXY(), std::abs(constituent.dcaXYZ()) * sign, constituent.sigmadcaXYZ(), static_cast(origConstit.itsNCls()), static_cast(origConstit.tpcNClsFound()), static_cast(origConstit.tpcNClsCrossedRows()), origConstit.itsChi2NCl(), origConstit.tpcChi2NCl()}; + tracksParams[minIdx] = std::vector{constituent.pt(), origConstit.phi(), constituent.eta(), static_cast(constituent.sign()), std::abs(constituent.dcaXY()) * sign, constituent.sigmadcaXY(), std::abs(constituent.dcaZ()) * sign, constituent.sigmadcaZ(), static_cast(origConstit.itsNCls()), static_cast(origConstit.tpcNClsFound()), static_cast(origConstit.tpcNClsCrossedRows()), origConstit.itsChi2NCl(), origConstit.tpcChi2NCl()}; } } } diff --git a/PWGJE/Tasks/bjetTreeCreator.cxx b/PWGJE/Tasks/bjetTreeCreator.cxx index a3ea1f8611f..5ffa3d103e2 100644 --- a/PWGJE/Tasks/bjetTreeCreator.cxx +++ b/PWGJE/Tasks/bjetTreeCreator.cxx @@ -327,9 +327,9 @@ struct BJetTreeCreator { registry.add("h_trk_phi", "trk_phi;#it{#phi};Entries", {HistType::kTH1F, {{200, 0., o2::constants::math::TwoPI}}}); registry.add("h_trk_charge", "trk_charge;#it{q};Entries", {HistType::kTH1F, {{3, -1.5, 1.5}}}); registry.add("h_trk_dcaxy", "trk_dcaxy;#it{DCA}_{xy} (cm);Entries", {HistType::kTH1F, {{200, -0.1, 0.1}}}); - registry.add("h_trk_dcaxyz", "trk_dcaxyz;#it{DCA}_{xyz} (cm);Entries", {HistType::kTH1F, {{200, -0.1, 0.1}}}); + registry.add("h_trk_dcaz", "trk_dcaxyz;#it{DCA}_{z} (cm);Entries", {HistType::kTH1F, {{200, -0.1, 0.1}}}); registry.add("h_trk_sigmadcaxy", "trk_sigmadcaxy;#it{#sigma}_{#it{DCA}_{xy}} (cm);Entries", {HistType::kTH1F, {{200, 0., 0.1}}}); - registry.add("h_trk_sigmadcaxyz", "trk_sigmadcaxyz;#it{#sigma}_{#it{DCA}_{xyz}} (cm);Entries", {HistType::kTH1F, {{200, 0., 0.1}}}); + registry.add("h_trk_sigmadcaz", "trk_sigmadcaxyz;#it{#sigma}_{#it{DCA}_{z}} (cm);Entries", {HistType::kTH1F, {{200, 0., 0.1}}}); registry.add("h_trk_itsncls", "trk_itsncls;ITS NCls;Entries", {HistType::kTH1F, {{10, 0., 10.}}}); registry.add("h_trk_tpcncls", "trk_tpcncls;TPC NCls (Found);Entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_trk_tpcncrs", "trk_tpcncrs;TPC NCrossedRows;Entries", {HistType::kTH1F, {{200, 0., 200.}}}); @@ -529,9 +529,9 @@ struct BJetTreeCreator { registry.fill(HIST("h_trk_phi"), origConstit.phi(), eventweight); registry.fill(HIST("h_trk_charge"), constituent.sign(), eventweight); registry.fill(HIST("h_trk_dcaxy"), std::abs(constituent.dcaXY()) * sign, eventweight); - registry.fill(HIST("h_trk_dcaxyz"), std::abs(constituent.dcaXYZ()) * sign, eventweight); + registry.fill(HIST("h_trk_dcaz"), std::abs(constituent.dcaZ()) * sign, eventweight); registry.fill(HIST("h_trk_sigmadcaxy"), constituent.sigmadcaXY(), eventweight); - registry.fill(HIST("h_trk_sigmadcaxyz"), constituent.sigmadcaXYZ(), eventweight); + registry.fill(HIST("h_trk_sigmadcaz"), constituent.sigmadcaZ(), eventweight); registry.fill(HIST("h_trk_itsncls"), origConstit.itsNCls(), eventweight); registry.fill(HIST("h_trk_tpcncls"), origConstit.tpcNClsFound(), eventweight); registry.fill(HIST("h_trk_tpcncrs"), origConstit.tpcNClsCrossedRows(), eventweight); diff --git a/PWGJE/Tasks/fullJetSpectra.cxx b/PWGJE/Tasks/fullJetSpectra.cxx index cdb14a1aa1c..80450cc1fa1 100644 --- a/PWGJE/Tasks/fullJetSpectra.cxx +++ b/PWGJE/Tasks/fullJetSpectra.cxx @@ -66,7 +66,7 @@ struct FullJetSpectra { Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable doEMCALEventWorkaround{"doEMCALEventWorkaround", false, "apply the workaround to read the EMC trigger bit by requiring a cell content in the EMCAL"}; - Configurable doMBGapTrigger{"doMBGapTrigger", true, "set to true only when using MB-Gap Trigger JJ MC to reject MB events at the collision and track level"}; + Configurable doMBGapTrigger{"doMBGapTrigger", false, "set to true only when using MB-Gap Trigger JJ MC to reject MB events at the collision and track level"}; // Software Trigger configurables Configurable doSoftwareTriggerSelection{"doSoftwareTriggerSelection", false, "set to true when using triggered datasets"}; @@ -135,6 +135,7 @@ struct FullJetSpectra { // Instantiate the Zorro processor for skimmed data and define an output object Zorro zorro; OutputObj zorroSummary{"zorroSummary"}; + const bool doSumw2 = doMBGapTrigger; // Multiplicity Utilities // struct CentClass { @@ -175,6 +176,19 @@ struct FullJetSpectra { // Add Collision Histograms' Bin Labels for clarity void labelCollisionHistograms(HistogramRegistry& registry) { + if (doprocessBCs) { + auto hBCCounter = registry.get(HIST("hBCCounter")); + hBCCounter->GetXaxis()->SetBinLabel(1, "AllBC"); + hBCCounter->GetXaxis()->SetBinLabel(2, "BC+TVX"); + hBCCounter->GetXaxis()->SetBinLabel(3, "BC+TVX+NoTFB"); + hBCCounter->GetXaxis()->SetBinLabel(4, "BC+TVX+NoTFB+NoITSROFB"); + hBCCounter->GetXaxis()->SetBinLabel(5, "CollinBC"); + hBCCounter->GetXaxis()->SetBinLabel(6, "CollinBC+Sel8"); + hBCCounter->GetXaxis()->SetBinLabel(7, "CollinBC+Sel8Full"); + hBCCounter->GetXaxis()->SetBinLabel(8, "CollinBC+Sel8Full+GoodZvtx"); + hBCCounter->GetXaxis()->SetBinLabel(9, "CollinBC+Sel8Full+VtxZ+GoodZvtx"); + } + if (doprocessDataTracks || doprocessMCTracks) { auto hCollisionsUnweighted = registry.get(HIST("hCollisionsUnweighted")); hCollisionsUnweighted->GetXaxis()->SetBinLabel(1, "allDetColl"); @@ -358,208 +372,219 @@ struct FullJetSpectra { jetRadiiBins.push_back(jetRadiiBins[jetRadiiBins.size() - 1] + 0.1); } + // Sanity Log check + if (doSumw2) { + LOGF(info, "HistogramRegistry initialized with Sumw2 = ON (weighted JJ MC mode)."); + } else { + LOGF(info, "HistogramRegistry initialized with Sumw2 = OFF (unweighted mode)."); + } + + if (doprocessBCs) { + registry.add("hBCCounter", "", {HistType::kTH1F, {{10, 0.0, 10.}}}, doSumw2); + } + // Track QA histograms if (doprocessDataTracks || doprocessMCTracks || doprocessTracksWeighted) { - registry.add("hCollisionsUnweighted", "event status; event status;entries", {HistType::kTH1F, {{12, 0., 12.0}}}); + registry.add("hCollisionsUnweighted", "event status; event status;entries", {HistType::kTH1F, {{12, 0., 12.0}}}, doSumw2); - registry.add("h_track_pt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_track_eta", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_track_phi", "track #varphi;#varphi_{track};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_track_energy", "track energy;Energy of tracks;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h_track_energysum", "track energy sum;Sum of track energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}); + registry.add("h_track_pt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_track_eta", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_track_phi", "track #varphi;#varphi_{track};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_track_energy", "track energy;Energy of tracks;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h_track_energysum", "track energy sum;Sum of track energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); // Cluster QA histograms - registry.add("h_clusterTime", "Time of cluster", HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}); - registry.add("h_cluster_pt", "cluster pT;#it{p}_{T_cluster} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); - registry.add("h_cluster_eta", "cluster #eta;#eta_{cluster};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_cluster_phi", "cluster #varphi;#varphi_{cluster};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_cluster_energy", "cluster energy;Energy of cluster;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h_cluster_energysum", "cluster energy sum;Sum of cluster energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}); + registry.add("h_clusterTime", "Time of cluster", HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}, doSumw2); + registry.add("h_cluster_pt", "cluster pT;#it{p}_{T_cluster} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}, doSumw2); + registry.add("h_cluster_eta", "cluster #eta;#eta_{cluster};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_cluster_phi", "cluster #varphi;#varphi_{cluster};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_cluster_energy", "cluster energy;Energy of cluster;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h_cluster_energysum", "cluster energy sum;Sum of cluster energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); if (doprocessTracksWeighted) { - registry.add("hCollisionsWeighted", "event status;event status;entries", {HistType::kTH1F, {{12, 0.0, 12.0}}}); + registry.add("hCollisionsWeighted", "event status;event status;entries", {HistType::kTH1F, {{12, 0.0, 12.0}}}, doSumw2); } } // Jet QA histograms if (doprocessJetsData || doprocessJetsMCD || doprocessJetsMCDWeighted) { - registry.add("hDetcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.}}}); - - registry.add("h_full_jet_pt", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_pt_pTHatcut", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_full_jet_clusterTime", "Time of cluster", HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}); - registry.add("h2_full_jet_nef", "#it{p}_{T,jet} vs nef at Det Level; #it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); - registry.add("h2_full_jet_nef_rejected", "#it{p}_{T,jet} vs nef at Det Level for rejected events; #it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); - - registry.add("h_Detjet_ntracks", "#it{p}_{T,track};#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h2_full_jet_chargedconstituents", "Number of charged constituents at Det Level;#it{p}_{T,jet} (GeV/#it{c});N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h2_full_jet_neutralconstituents", "Number of neutral constituents at Det Level;#it{p}_{T,jet} (GeV/#it{c});N_{ne}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h_full_jet_chargedconstituents_pt", "track pT;#it{p}^{T,jet}_{track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_chargedconstituents_eta", "track #eta;#eta^{jet}_{track};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_jet_chargedconstituents_phi", "track #varphi;#varphi^{jet}_{track};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_full_jet_chargedconstituents_energy", "track energy;Energy of tracks;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h_full_jet_chargedconstituents_energysum", "track energy sum;Sum of track energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h_full_jet_neutralconstituents_pt", "cluster pT;#it{p}^{T,jet}_{cluster} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); - registry.add("h_full_jet_neutralconstituents_eta", "cluster #eta;#eta^{jet}_{cluster};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_jet_neutralconstituents_phi", "cluster #varphi;#varphi^{jet}_{cluster};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_full_jet_neutralconstituents_energy", "cluster energy;Energy of cluster;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h_full_jet_neutralconstituents_energysum", "cluster energy sum;Sum of cluster energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h2_full_jettrack_pt", "#it{p}_{T,jet} vs #it{p}_{T,track}; #it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{350, 0., 350.}, {200, 0., 200.}}}); - registry.add("h2_full_jettrack_eta", "jet #eta vs jet_track #eta; #eta_{jet};#eta_{track}", {HistType::kTH2F, {{100, -1., 1.}, {500, -5., 5.}}}); - registry.add("h2_full_jettrack_phi", "jet #varphi vs jet_track #varphi; #varphi_{jet}; #varphi_{track}", {HistType::kTH2F, {{160, 0., 7.}, {160, -1., 7.}}}); - - registry.add("h2_track_etaphi", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}); - registry.add("h2_jet_etaphi", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); + registry.add("hDetcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.}}}, doSumw2); + + registry.add("h_full_jet_pt", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_pt_pTHatcut", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_full_jet_clusterTime", "Time of cluster", HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}, doSumw2); + registry.add("h2_full_jet_nef", "#it{p}_{T,jet} vs nef at Det Level; #it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}, doSumw2); + registry.add("h2_full_jet_nef_rejected", "#it{p}_{T,jet} vs nef at Det Level for rejected events; #it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}, doSumw2); + + registry.add("h_Detjet_ntracks", "#it{p}_{T,track};#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h2_full_jet_chargedconstituents", "Number of charged constituents at Det Level;#it{p}_{T,jet} (GeV/#it{c});N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}, doSumw2); + registry.add("h2_full_jet_neutralconstituents", "Number of neutral constituents at Det Level;#it{p}_{T,jet} (GeV/#it{c});N_{ne}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}, doSumw2); + registry.add("h_full_jet_chargedconstituents_pt", "track pT;#it{p}^{T,jet}_{track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_chargedconstituents_eta", "track #eta;#eta^{jet}_{track};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_jet_chargedconstituents_phi", "track #varphi;#varphi^{jet}_{track};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_full_jet_chargedconstituents_energy", "track energy;Energy of tracks;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h_full_jet_chargedconstituents_energysum", "track energy sum;Sum of track energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_pt", "cluster pT;#it{p}^{T,jet}_{cluster} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_eta", "cluster #eta;#eta^{jet}_{cluster};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_phi", "cluster #varphi;#varphi^{jet}_{cluster};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_energy", "cluster energy;Energy of cluster;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_energysum", "cluster energy sum;Sum of cluster energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h2_full_jettrack_pt", "#it{p}_{T,jet} vs #it{p}_{T,track}; #it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{350, 0., 350.}, {200, 0., 200.}}}, doSumw2); + registry.add("h2_full_jettrack_eta", "jet #eta vs jet_track #eta; #eta_{jet};#eta_{track}", {HistType::kTH2F, {{100, -1., 1.}, {500, -5., 5.}}}, doSumw2); + registry.add("h2_full_jettrack_phi", "jet #varphi vs jet_track #varphi; #varphi_{jet}; #varphi_{track}", {HistType::kTH2F, {{160, 0., 7.}, {160, -1., 7.}}}, doSumw2); + + registry.add("h2_track_etaphi", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}, doSumw2); + registry.add("h2_jet_etaphi", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}, doSumw2); } if (doprocessJetsTriggeredData) { - registry.add("hDetTrigcollisionCounter", "event status;;entries", {HistType::kTH1F, {{14, 0.0, 14.}}}); + registry.add("hDetTrigcollisionCounter", "event status;;entries", {HistType::kTH1F, {{14, 0.0, 14.}}}, doSumw2); } if (doprocessJetsMCP || doprocessJetsMCPWeighted) { - registry.add("hPartcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); - registry.add("hRecoMatchesPerMcCollision", "split vertices QA;;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}); - - registry.add("h_full_mcpjet_tablesize", "", {HistType::kTH1F, {{4, 0., 5.}}}); - registry.add("h_full_mcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); - registry.add("h_full_jet_pt_part", "jet pT;#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_eta_part", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_jet_phi_part", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h2_full_jet_nef_part", "#it{p}_{T,jet} vs nef at Part Level;#it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); - - registry.add("h_Partjet_ntracks", "#it{p}_{T,constituent};#it{p}_{T_constituent} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h2_full_jet_chargedconstituents_part", "Number of charged constituents at Part Level;#it{p}_{T,jet} (GeV/#it{c});N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h2_full_jet_neutralconstituents_part", "Number of neutral constituents at Part Level;#it{p}_{T,jet} (GeV/#it{c});N_{ne}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h_full_jet_neutralconstituents_pt_part", "#it{p}_{T} of neutral constituents at Part Level;#it{p}_{T,ne} (GeV/#it{c}); entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_neutralconstituents_eta_part", "#eta of neutral constituents at Part Level;#eta_{ne};entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_neutralconstituents_phi_part", "#varphi of neutral constituents at Part Level;#varphi_{ne};entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_jet_neutralconstituents_energy_part", "neutral constituents' energy;Energy of neutral constituents;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - registry.add("h_full_jet_neutralconstituents_energysum_part", "neutral constituents' energy sum;Sum of neutral constituents' energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}); - - registry.add("h2_jettrack_pt_part", "#it{p}_{T,jet} vs #it{p}_{T_track}; #it{p}_{T_jet} (GeV/#it{c});#it{p}_{T_track} (GeV/#it{c})", {HistType::kTH2F, {{350, 0., 350.}, {200, 0., 200.}}}); - registry.add("h2_jettrack_eta_part", "jet #eta vs jet_track #eta; #eta_{jet};#eta_{track}", {HistType::kTH2F, {{100, -1., 1.}, {500, -5., 5.}}}); - registry.add("h2_jettrack_phi_part", "jet #varphi vs jet_track #varphi; #varphi_{jet}; #varphi_{track}", {HistType::kTH2F, {{160, 0., 7.}, {160, -1., 7.}}}); - - registry.add("h2_track_etaphi_part", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}); - registry.add("h2_jet_etaphi_part", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); + registry.add("hPartcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}, doSumw2); + registry.add("hRecoMatchesPerMcCollision", "split vertices QA;;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}, doSumw2); + + registry.add("h_full_mcpjet_tablesize", "", {HistType::kTH1F, {{4, 0., 5.}}}, doSumw2); + registry.add("h_full_mcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}, doSumw2); + registry.add("h_full_jet_pt_part", "jet pT;#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_eta_part", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_jet_phi_part", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h2_full_jet_nef_part", "#it{p}_{T,jet} vs nef at Part Level;#it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}, doSumw2); + + registry.add("h_Partjet_ntracks", "#it{p}_{T,constituent};#it{p}_{T_constituent} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h2_full_jet_chargedconstituents_part", "Number of charged constituents at Part Level;#it{p}_{T,jet} (GeV/#it{c});N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}, doSumw2); + registry.add("h2_full_jet_neutralconstituents_part", "Number of neutral constituents at Part Level;#it{p}_{T,jet} (GeV/#it{c});N_{ne}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_pt_part", "#it{p}_{T} of neutral constituents at Part Level;#it{p}_{T,ne} (GeV/#it{c}); entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_eta_part", "#eta of neutral constituents at Part Level;#eta_{ne};entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_phi_part", "#varphi of neutral constituents at Part Level;#varphi_{ne};entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_energy_part", "neutral constituents' energy;Energy of neutral constituents;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + registry.add("h_full_jet_neutralconstituents_energysum_part", "neutral constituents' energy sum;Sum of neutral constituents' energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}, doSumw2); + + registry.add("h2_jettrack_pt_part", "#it{p}_{T,jet} vs #it{p}_{T_track}; #it{p}_{T_jet} (GeV/#it{c});#it{p}_{T_track} (GeV/#it{c})", {HistType::kTH2F, {{350, 0., 350.}, {200, 0., 200.}}}, doSumw2); + registry.add("h2_jettrack_eta_part", "jet #eta vs jet_track #eta; #eta_{jet};#eta_{track}", {HistType::kTH2F, {{100, -1., 1.}, {500, -5., 5.}}}, doSumw2); + registry.add("h2_jettrack_phi_part", "jet #varphi vs jet_track #varphi; #varphi_{jet}; #varphi_{track}", {HistType::kTH2F, {{160, 0., 7.}, {160, -1., 7.}}}, doSumw2); + + registry.add("h2_track_etaphi_part", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}, doSumw2); + registry.add("h2_jet_etaphi_part", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}, doSumw2); // registry.add("h_NOmcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); // registry.add("h_mcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); - registry.add("h2_full_mcpjetOutsideFiducial_pt", "MCP jet outside EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); - registry.add("h_full_mcpjetOutside_eta_part", "MCP jet #eta outside EMC Fiducial Acceptance;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_mcpjetOutside_phi_part", "MCP jet #varphi outside EMC Fiducial Acceptance;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h2_full_mcpjetInsideFiducial_pt", "MCP jet #it{p}_{T,part} inside EMC Fiducial Acceptance;#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); - registry.add("h_full_mcpjetInside_eta_part", "MCP jet #eta inside EMC Fiducial Acceptance;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_mcpjetInside_phi_part", "MCP jet #varphi inside EMC Fiducial Acceptance;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); + registry.add("h2_full_mcpjetOutsideFiducial_pt", "MCP jet outside EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}, doSumw2); + registry.add("h_full_mcpjetOutside_eta_part", "MCP jet #eta outside EMC Fiducial Acceptance;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_mcpjetOutside_phi_part", "MCP jet #varphi outside EMC Fiducial Acceptance;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h2_full_mcpjetInsideFiducial_pt", "MCP jet #it{p}_{T,part} inside EMC Fiducial Acceptance;#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}, doSumw2); + registry.add("h_full_mcpjetInside_eta_part", "MCP jet #eta inside EMC Fiducial Acceptance;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_mcpjetInside_phi_part", "MCP jet #varphi inside EMC Fiducial Acceptance;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); } if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { - registry.add("hMatchedcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); - - registry.add("h_full_matchedmcdjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_matchedmcpjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_full_matchedmcdjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); - registry.add("h_full_matchedmcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); - registry.add("h_full_matchedmcdjet_eta", "Matched MCD jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_matchedmcdjet_phi", "Matched MCD jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_full_matchedmcpjet_eta", "Matched MCP jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); - registry.add("h_full_matchedmcpjet_phi", "Matched MCP jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h_full_jet_deltaR", "Distance between matched Det Jet and Part Jet; #Delta R; entries", {HistType::kTH1F, {{100, 0., 1.}}}); - - registry.add("h2_full_jet_energyscaleDet", "Jet Energy Scale (det); p_{T,det} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); - - registry.add("h2_matchedjet_etaphiDet", "Det jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); - registry.add("h2_matchedjet_etaphiPart", "Part jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); - registry.add("h2_matchedjet_deltaEtaCorr", "Correlation between Det Eta and Part Eta; #eta_{jet,det}; #eta_{jet,part}", {HistType::kTH2F, {{100, -1., 1.}, {100, -1., 1.}}}); - registry.add("h2_matchedjet_deltaPhiCorr", "Correlation between Det Phi and Part Phi; #varphi_{jet,det}; #varphi_{jet,part}", {HistType::kTH2F, {{160, 0., 7.}, {160, 0., 7.}}}); - - registry.add("h2_full_jet_energyscalePart", "Jet Energy Scale (part); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); - registry.add("h3_full_jet_energyscalePart", "R dependence of Jet Energy Scale (Part); #it{R}_{jet};p_{T,det} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {400, 0., 400.}, {200, -1., 1.}}}); - registry.add("h2_full_jet_etaresolutionPart", ";p_{T,part} (GeV/c); (#eta_{jet,det} - #eta_{jet,part})/#eta_{jet,part}", {HistType::kTH2F, {{400, 0., 400.}, {100, -1., 1.}}}); - registry.add("h2_full_jet_phiresolutionPart", ";p_{T,part} (GeV/c); (#varphi_{jet,det} - #varphi_{jet,part})/#varphi_{jet,part}", {HistType::kTH2F, {{400, 0., 400.}, {160, -1., 7.}}}); - registry.add("h2_full_jet_energyscaleChargedPart", "Jet Energy Scale (charged part); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); - registry.add("h2_full_jet_energyscaleNeutralPart", "Jet Energy Scale (neutral part); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); - registry.add("h2_full_jet_energyscaleChargedVsFullPart", "Jet Energy Scale (charged part, vs. full jet pt); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); - registry.add("h2_full_jet_energyscaleNeutralVsFullPart", "Jet Energy Scale (neutral part, vs. full jet pt); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); - registry.add("h2_full_fakemcdjets", "Fake MCD Jets; p_{T,det} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h2FullfakeMcpJets", "Fake MCP Jets; p_{T,part} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h2_full_matchedmcpjet_pt", "Matched MCP jet in EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); + registry.add("hMatchedcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}, doSumw2); + + registry.add("h_full_matchedmcdjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_matchedmcpjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_full_matchedmcdjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}, doSumw2); + registry.add("h_full_matchedmcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}, doSumw2); + registry.add("h_full_matchedmcdjet_eta", "Matched MCD jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_matchedmcdjet_phi", "Matched MCD jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_full_matchedmcpjet_eta", "Matched MCP jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}, doSumw2); + registry.add("h_full_matchedmcpjet_phi", "Matched MCP jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}, doSumw2); + registry.add("h_full_jet_deltaR", "Distance between matched Det Jet and Part Jet; #Delta R; entries", {HistType::kTH1F, {{100, 0., 1.}}}, doSumw2); + + registry.add("h2_full_jet_energyscaleDet", "Jet Energy Scale (det); p_{T,det} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + + registry.add("h2_matchedjet_etaphiDet", "Det jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}, doSumw2); + registry.add("h2_matchedjet_etaphiPart", "Part jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}, doSumw2); + registry.add("h2_matchedjet_deltaEtaCorr", "Correlation between Det Eta and Part Eta; #eta_{jet,det}; #eta_{jet,part}", {HistType::kTH2F, {{100, -1., 1.}, {100, -1., 1.}}}, doSumw2); + registry.add("h2_matchedjet_deltaPhiCorr", "Correlation between Det Phi and Part Phi; #varphi_{jet,det}; #varphi_{jet,part}", {HistType::kTH2F, {{160, 0., 7.}, {160, 0., 7.}}}, doSumw2); + + registry.add("h2_full_jet_energyscalePart", "Jet Energy Scale (part); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + registry.add("h3_full_jet_energyscalePart", "R dependence of Jet Energy Scale (Part); #it{R}_{jet};p_{T,det} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + registry.add("h2_full_jet_etaresolutionPart", ";p_{T,part} (GeV/c); (#eta_{jet,det} - #eta_{jet,part})/#eta_{jet,part}", {HistType::kTH2F, {{400, 0., 400.}, {100, -1., 1.}}}, doSumw2); + registry.add("h2_full_jet_phiresolutionPart", ";p_{T,part} (GeV/c); (#varphi_{jet,det} - #varphi_{jet,part})/#varphi_{jet,part}", {HistType::kTH2F, {{400, 0., 400.}, {160, -1., 7.}}}, doSumw2); + registry.add("h2_full_jet_energyscaleChargedPart", "Jet Energy Scale (charged part); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + registry.add("h2_full_jet_energyscaleNeutralPart", "Jet Energy Scale (neutral part); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + registry.add("h2_full_jet_energyscaleChargedVsFullPart", "Jet Energy Scale (charged part, vs. full jet pt); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + registry.add("h2_full_jet_energyscaleNeutralVsFullPart", "Jet Energy Scale (neutral part, vs. full jet pt); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}, doSumw2); + registry.add("h2_full_fakemcdjets", "Fake MCD Jets; p_{T,det} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}, doSumw2); + registry.add("h2FullfakeMcpJets", "Fake MCP Jets; p_{T,part} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}, doSumw2); + registry.add("h2_full_matchedmcpjet_pt", "Matched MCP jet in EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}, doSumw2); // Response Matrix - registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{500, 0., 500.}, {500, 0., 500.}}}); + registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{500, 0., 500.}, {500, 0., 500.}}}, doSumw2); } if (doprocessMBCollisionsDATAWithMultiplicity || doprocessMBMCDCollisionsWithMultiplicity || doprocessMCDCollisionsWeightedWithMultiplicity) { - registry.add("hEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); - registry.add("h_FT0Mults_occupancy", "", {HistType::kTH1F, {{3500, 0., 3500.}}}); - - registry.add("h_all_fulljet_Njets", "Full Jet Multiplicity (per Event)", {HistType::kTH1F, {{20, 0., 20.}}}); - registry.add("h_Leading_full_jet_pt", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h2_full_jet_leadingJetPt_vs_counts", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); - registry.add("h_SubLeading_full_jet_pt", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h2_full_jet_subLeadingJetPt_vs_counts", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); + registry.add("hEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}, doSumw2); + registry.add("h_FT0Mults_occupancy", "", {HistType::kTH1F, {{3500, 0., 3500.}}}, doSumw2); + + registry.add("h_all_fulljet_Njets", "Full Jet Multiplicity (per Event)", {HistType::kTH1F, {{20, 0., 20.}}}, doSumw2); + registry.add("h_Leading_full_jet_pt", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h2_full_jet_leadingJetPt_vs_counts", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}, doSumw2); + registry.add("h_SubLeading_full_jet_pt", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h2_full_jet_subLeadingJetPt_vs_counts", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}, doSumw2); // Inside Jet Loop: // CASE 1: - registry.add("h_all_fulljet_pt", "#it{p}_{T,fulljet};#it{p}_{T_fulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_all_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); - registry.add("h_all_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); - registry.add("h2_all_fulljet_jetpTDet_vs_FT0Mults", "; p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h2_all_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_fulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); - registry.add("h3_full_jet_jetpTDet_FT0Mults_nef", "; p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + registry.add("h_all_fulljet_pt", "#it{p}_{T,fulljet};#it{p}_{T_fulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_all_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}, doSumw2); + registry.add("h_all_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}, doSumw2); + registry.add("h2_all_fulljet_jetpTDet_vs_FT0Mults", "; p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}, doSumw2); + registry.add("h2_all_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_fulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}, doSumw2); + registry.add("h3_full_jet_jetpTDet_FT0Mults_nef", "; p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}, doSumw2); // CASE 2: - registry.add("h_leading_fulljet_pt", "#it{p}_{T,Leading fulljet};#it{p}_{T_Leadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_leading_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); - registry.add("h_leading_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); - registry.add("h2_leading_fulljet_jetpTDet_vs_FT0Mults", ";Leading p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h2_leading_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_Leadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); - registry.add("h3_leading_fulljet_jetpTDet_FT0Mults_nef", "; Leading p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + registry.add("h_leading_fulljet_pt", "#it{p}_{T,Leading fulljet};#it{p}_{T_Leadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_leading_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}, doSumw2); + registry.add("h_leading_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}, doSumw2); + registry.add("h2_leading_fulljet_jetpTDet_vs_FT0Mults", ";Leading p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}, doSumw2); + registry.add("h2_leading_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_Leadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}, doSumw2); + registry.add("h3_leading_fulljet_jetpTDet_FT0Mults_nef", "; Leading p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}, doSumw2); // CASE 3: - registry.add("h_subleading_fulljet_pt", "#it{p}_{T,SubLeading fulljet};#it{p}_{T_SubLeadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_subleading_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); - registry.add("h_subleading_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); - registry.add("h2_subleading_fulljet_jetpTDet_vs_FT0Mults", ";SubLeading p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h2_subleading_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_SubLeadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); - registry.add("h3_subleading_fulljet_jetpTDet_FT0Mults_nef", "; SubLeading p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + registry.add("h_subleading_fulljet_pt", "#it{p}_{T,SubLeading fulljet};#it{p}_{T_SubLeadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_subleading_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}, doSumw2); + registry.add("h_subleading_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}, doSumw2); + registry.add("h2_subleading_fulljet_jetpTDet_vs_FT0Mults", ";SubLeading p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}, doSumw2); + registry.add("h2_subleading_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_SubLeadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}, doSumw2); + registry.add("h3_subleading_fulljet_jetpTDet_FT0Mults_nef", "; SubLeading p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}, doSumw2); } if (doprocessMBMCPCollisionsWithMultiplicity || doprocessMBMCPCollisionsWeightedWithMultiplicity) { - registry.add("hPartEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{11, 0.0, 11.0}}}); - registry.add("hRecoMatchesPerMcCollisionMult", "split vertices QA;;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}); - registry.add("hMCCollMatchedFT0Mult", "", {HistType::kTH1F, {{3500, 0., 3500.}}}); - registry.add("hMCCollMatchedFT0Cent", "", {HistType::kTH1F, {{105, 0., 105.}}}); + registry.add("hPartEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{11, 0.0, 11.0}}}, doSumw2); + registry.add("hRecoMatchesPerMcCollisionMult", "split vertices QA;;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}, doSumw2); + registry.add("hMCCollMatchedFT0Mult", "", {HistType::kTH1F, {{3500, 0., 3500.}}}, doSumw2); + registry.add("hMCCollMatchedFT0Cent", "", {HistType::kTH1F, {{105, 0., 105.}}}, doSumw2); - registry.add("h_all_fulljet_Njets_part", "Full Jet Multiplicity (per Event)", {HistType::kTH1F, {{20, 0., 20.}}}); - registry.add("h_Leading_full_jet_pt_part", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h2_full_jet_leadingJetPt_vs_counts_part", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); - registry.add("h_SubLeading_full_jet_pt_part", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h2_full_jet_subLeadingJetPt_vs_counts_part", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); + registry.add("h_all_fulljet_Njets_part", "Full Jet Multiplicity (per Event)", {HistType::kTH1F, {{20, 0., 20.}}}, doSumw2); + registry.add("h_Leading_full_jet_pt_part", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h2_full_jet_leadingJetPt_vs_counts_part", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}, doSumw2); + registry.add("h_SubLeading_full_jet_pt_part", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h2_full_jet_subLeadingJetPt_vs_counts_part", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}, doSumw2); // Inside Jet Loop: // CASE 1: - registry.add("h_all_fulljet_pt_part", "#it{p}_{T,fulljet};#it{p}_{T_fulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_all_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); - registry.add("h_all_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}); - registry.add("h_all_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); - registry.add("h2_all_fulljet_jetpT_vs_FT0Mults_part", "; p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h2_all_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_fulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); - registry.add("h3_full_jet_jetpT_FT0Mults_nef_part", "; p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + registry.add("h_all_fulljet_pt_part", "#it{p}_{T,fulljet};#it{p}_{T_fulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_all_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}, doSumw2); + registry.add("h_all_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}, doSumw2); + registry.add("h_all_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}, doSumw2); + registry.add("h2_all_fulljet_jetpT_vs_FT0Mults_part", "; p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}, doSumw2); + registry.add("h2_all_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_fulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}, doSumw2); + registry.add("h3_full_jet_jetpT_FT0Mults_nef_part", "; p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}, doSumw2); // CASE 2: - registry.add("h_leading_fulljet_pt_part", "#it{p}_{T,Leading fulljet};#it{p}_{T_Leadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_leading_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); - registry.add("h_leading_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}); - registry.add("h_leading_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); - registry.add("h2_leading_fulljet_jetpT_vs_FT0Mults_part", ";Leading p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h2_leading_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_Leadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); - registry.add("h3_leading_fulljet_jetpT_FT0Mults_nef_part", "; Leading p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + registry.add("h_leading_fulljet_pt_part", "#it{p}_{T,Leading fulljet};#it{p}_{T_Leadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_leading_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}, doSumw2); + registry.add("h_leading_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}, doSumw2); + registry.add("h_leading_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}, doSumw2); + registry.add("h2_leading_fulljet_jetpT_vs_FT0Mults_part", ";Leading p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}, doSumw2); + registry.add("h2_leading_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_Leadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}, doSumw2); + registry.add("h3_leading_fulljet_jetpT_FT0Mults_nef_part", "; Leading p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}, doSumw2); // CASE 3: - registry.add("h_subleading_fulljet_pt_part", "#it{p}_{T,SubLeading fulljet};#it{p}_{T_SubLeadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_subleading_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); - registry.add("h_subleading_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}); - registry.add("h_subleading_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); - registry.add("h2_subleading_fulljet_jetpT_vs_FT0Mults_part", ";SubLeading p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h2_subleading_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_SubLeadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); - registry.add("h3_subleading_fulljet_jetpT_FT0Mults_nef_part", "; SubLeading p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + registry.add("h_subleading_fulljet_pt_part", "#it{p}_{T,SubLeading fulljet};#it{p}_{T_SubLeadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}, doSumw2); + registry.add("h_subleading_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}, doSumw2); + registry.add("h_subleading_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}, doSumw2); + registry.add("h_subleading_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}, doSumw2); + registry.add("h2_subleading_fulljet_jetpT_vs_FT0Mults_part", ";SubLeading p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}, doSumw2); + registry.add("h2_subleading_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_SubLeadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}, doSumw2); + registry.add("h3_subleading_fulljet_jetpT_FT0Mults_nef_part", "; SubLeading p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}, doSumw2); } // Label the histograms @@ -625,6 +650,7 @@ struct FullJetSpectra { Filter clusterFilter = (aod::jcluster::definition == static_cast(clusterDefinition) && aod::jcluster::eta > clusterEtaMin && aod::jcluster::eta < clusterEtaMax && aod::jcluster::phi >= clusterPhiMin && aod::jcluster::phi <= clusterPhiMax && aod::jcluster::energy >= clusterEnergyMin && aod::jcluster::time > clusterTimeMin && aod::jcluster::time < clusterTimeMax && (clusterRejectExotics && aod::jcluster::isExotic != true)); Preslice JetMCPPerMcCollision = aod::jet::mcCollisionId; PresliceUnsorted> CollisionsPerMCPCollision = aod::jmccollisionlb::mcCollisionId; + PresliceUnsorted> perFoundBC = aod::evsel::foundBCId; template bool isAcceptedRecoJet(U const& jet) @@ -890,6 +916,42 @@ struct FullJetSpectra { } PROCESS_SWITCH(FullJetSpectra, processDummy, "dummy task", true); + void processBCs(o2::soa::Join const& bcs, o2::soa::Join const& collisions) + { + if (bcs.size() == 0) { + return; + } + for (auto bc : bcs) { + registry.fill(HIST("hBCCounter"), 0.5); // All BC + if (bc.selection_bit(aod::evsel::kIsTriggerTVX)) { + registry.fill(HIST("hBCCounter"), 1.5); // BC+TVX + if (bc.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + registry.fill(HIST("hBCCounter"), 2.5); // BC+TVX+NoTFB + if (bc.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + registry.fill(HIST("hBCCounter"), 3.5); // BC+TVX+NoTFB+NoITSROFB ----> this goes to Lumi i.e. hLumiAfterBCcuts in eventSelection task + } + } + } + auto collisionsInBC = collisions.sliceBy(perFoundBC, bc.globalIndex()); + for (auto collision : collisionsInBC) { + registry.fill(HIST("hBCCounter"), 4.5); // CollinBC + if (collision.sel8()) { + registry.fill(HIST("hBCCounter"), 5.5); // CollinBC+sel8 + if (collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + registry.fill(HIST("hBCCounter"), 6.5); // CollinBC+sel8Full + if (collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + registry.fill(HIST("hBCCounter"), 7.5); // CollinBC+sel8Full+GoodZvtx + if (std::fabs(collision.posZ()) < vertexZCut) { + registry.fill(HIST("hBCCounter"), 8.5); // CollinBC+sel8Full+VtxZ+GoodZvtx ----> this goes to my analysis task for jet events selection + } + } + } + } + } // collision loop + } // bc loop + } + PROCESS_SWITCH(FullJetSpectra, processBCs, "BCs for 0 vertex QA", false); + void processJetsData(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { bool eventAccepted = false; @@ -1092,8 +1154,8 @@ struct FullJetSpectra { registry.fill(HIST("hSpliteventSelector"), 0.5); // 20% Closure input for the measured spectra (reco) registry.fill(HIST("h_MCD_splitevent_counter"), 0.5); - } - */ +} +*/ registry.fill(HIST("hDetcollisionCounter"), 0.5); // allDetColl if (std::fabs(collision.posZ()) > vertexZCut) { return; @@ -1944,8 +2006,7 @@ struct FullJetSpectra { // Verify jet-collision association for (auto const& jet : jets) { if (jet.collisionId() != collision.globalIndex()) { - std::cout << "WARNING: Jet with pT " << jet.pt() << " belongs to collision " << jet.collisionId() - << " but processing collision " << collision.globalIndex() << std::endl; + LOGF(warn, "Jet with pT %.2f belongs to collision %d but processing collision %d", jet.pt(), jet.collisionId(), collision.globalIndex()); continue; } @@ -2013,8 +2074,9 @@ struct FullJetSpectra { for (const auto& jettrack : jet.tracks_as()) { if (jetderiveddatautilities::selectTrack(jettrack, trackSelection)) { numberOfChargedParticles++; - } else + } else { continue; + } } // Calculate neutral energy fraction for this jet @@ -2103,8 +2165,7 @@ struct FullJetSpectra { // Verify jet-collision association for (auto const& mcdjet : mcdjets) { if (mcdjet.collisionId() != collision.globalIndex()) { - std::cout << "WARNING: Jet with pT " << mcdjet.pt() << " belongs to collision " << mcdjet.collisionId() - << " but processing collision " << collision.globalIndex() << std::endl; + LOGF(warn, "Jet with pT %.2f belongs to collision %d but processing collision %d", mcdjet.pt(), mcdjet.collisionId(), collision.globalIndex()); continue; } @@ -2157,8 +2218,9 @@ struct FullJetSpectra { for (const auto& jettrack : jet.tracks_as()) { if (jetderiveddatautilities::selectTrack(jettrack, trackSelection)) { numberOfChargedParticles++; - } else + } else { continue; + } } // Calculate neutral energy fraction for this jet @@ -2259,8 +2321,7 @@ struct FullJetSpectra { float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); if (mcdjet.collisionId() != collision.globalIndex()) { - std::cout << "WARNING: Jet with pT " << mcdjet.pt() << " belongs to collision " << mcdjet.collisionId() - << " but processing collision " << collision.globalIndex() << std::endl; + LOGF(warn, "Jet with pT %.2f belongs to collision %d but processing collision %d", mcdjet.pt(), mcdjet.collisionId(), collision.globalIndex()); continue; } @@ -2316,8 +2377,9 @@ struct FullJetSpectra { for (const auto& jettrack : jet.tracks_as()) { if (jetderiveddatautilities::selectTrack(jettrack, trackSelection)) { numberOfChargedParticles++; - } else + } else { continue; + } } // Calculate neutral energy fraction for this jet diff --git a/PWGJE/Tasks/jetChargedV2.cxx b/PWGJE/Tasks/jetChargedV2.cxx index 4c5cd82ed25..008cd65ca02 100644 --- a/PWGJE/Tasks/jetChargedV2.cxx +++ b/PWGJE/Tasks/jetChargedV2.cxx @@ -58,7 +58,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct JetChargedV2 { - using McParticleCollision = soa::Join; + using McParticleCollision = soa::Join; using ChargedMCDMatchedJets = soa::Join; using ChargedMCPMatchedJets = soa::Join; @@ -126,6 +126,7 @@ struct JetChargedV2 { Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; Configurable checkLeadConstituentPtForMcpJets{"checkLeadConstituentPtForMcpJets", false, "flag to choose whether particle level jets should have their lead track pt above leadingConstituentPtMin to be accepted; off by default, as leadingConstituentPtMin cut is only applied on MCD jets for the Pb-Pb analysis using pp MC anchored to Pb-Pb for the response matrix"}; Configurable cfgChkFitQuality{"cfgChkFitQuality", false, "check fit quality"}; + Configurable subtractMCPBackground{"subtractMCPBackground", true, "subtract MCP Background with General Purpose anchored MC"}; template int getDetId(const T& name) @@ -259,6 +260,7 @@ struct JetChargedV2 { histosQA.add("histCent", "Centrality TrkProcess", HistType::kTH1F, {axisCent}); //< Track efficiency plots >// registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + registry.add("h_collisions_Zvertex", "position of collision ;#it{Z} (cm)", {HistType::kTH1F, {{300, -15.0, 15.0}}}); //< fit quality >// registry.add("h_PvalueCDF_CombinFit", "cDF #chi^{2}; entries", {HistType::kTH1F, {{50, 0, 1}}}); registry.add("h2_PvalueCDFCent_CombinFit", "p-value cDF vs centrality; centrality; p-value", {HistType::kTH2F, {{100, 0, 100}, {40, 0, 1}}}); @@ -317,7 +319,11 @@ struct JetChargedV2 { registry.add("h2_jet_pt_track_pt_rhoareasubtracted", "jet #it{p}_{T,jet} vs. #it{p}_{T,track}; #it{p}_{T,jet} (GeV/#it{c}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {jetPtAxisRhoAreaSub, trackPtAxis}}); } - if (doprocessSigmaPtMCP) { + if (doprocessSigmaPtMCP || doprocessSigmaPtAreaSubMCP) { + registry.add("h_jet_pt_part", "partvjet pT;#it{p}_{T,jet}^{part} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxis}}); + registry.add("h_jet_eta_part", "part jet #eta;#eta^{part}; counts", {HistType::kTH1F, {jetEtaAxis}}); + registry.add("h_jet_phi_part", "part jet #varphi;#phi^{part}; counts", {HistType::kTH1F, {phiAxis}}); + registry.add("h_jet_pt_part_rhoareasubtracted", "part jet corr pT;#it{p}_{T,jet}^{part} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_jet_eta_part_rhoareasubtracted", "part jet #eta;#eta^{part}; counts", {HistType::kTH1F, {jetEtaAxis}}); registry.add("h_jet_phi_part_rhoareasubtracted", "part jet #varphi;#varphi^{part}; counts", {HistType::kTH1F, {phiAxis}}); @@ -326,17 +332,21 @@ struct JetChargedV2 { registry.add("leadJetPhiMCP", "MCP leadJet constituent #phi ", {HistType::kTH1F, {{80, -1.0, 7.}}}); registry.add("leadJetEtaMCP", "MCP leadJet constituent #eta ", {HistType::kTH1F, {{100, -1.0, 1.0}}}); - registry.add("h2_mcp_phi_rholocal", "#varphi vs #rho(#varphi); #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); - registry.add("h2_mcp_centrality_rholocal", "#varphi vs #rho(#varphi); #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{120, -10.0, 110.0}, {210, -10.0, 200.0}}}); - registry.add("h_mcp_jet_pt_rholocal", "jet pT rholocal;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); - //< MCP fit test >// - registry.add("h_mcp_evtnum_centrlity", "eventNumber vs centrality ; #eventNumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); registry.add("h_mcp_v2obs_centrality", "fitparameter v2obs vs centrality ; #centrality", {HistType::kTProfile, {cfgAxisVnCent}}); registry.add("h_mcp_v3obs_centrality", "fitparameter v3obs vs centrality ; #centrality", {HistType::kTProfile, {cfgAxisVnCent}}); registry.add("h_mcp_fitparaRho_evtnum", "fitparameter #rho_{0} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); registry.add("h_mcp_fitparaPsi2_evtnum", "fitparameter #Psi_{2} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); registry.add("h_mcp_fitparaPsi3_evtnum", "fitparameter #Psi_{3} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); + registry.add("h2_mcp_phi_rholocal", "#varphi vs #rho(#varphi); #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_mcp_centrality_rholocal", "#varphi vs #rho(#varphi); #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{120, -10.0, 110.0}, {210, -10.0, 200.0}}}); + registry.add("h_mcp_jet_pt_rhoareasubtracted", "jet pT rholocal;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); + registry.add("h_mcp_jet_pt_rholocal", "jet pT rholocal;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); + //< MCP fit test >// + registry.add("h_mcp_evtnum_centrlity", "eventNumber vs centrality ; #eventNumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); + registry.add("h_ep2_evtnum", "fitparameter #rho_{0} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); + registry.add("h_ep3_evtnum", "fitparameter #Psi_{2} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); + registry.add("h_mcp_jet_pt_in_plane_v2_rho", "jet pT;#it{p}^{in-plane}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_mcp_jet_pt_out_of_plane_v2_rho", "jet pT;#it{p}^{out-of-plane}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_mcp_jet_pt_in_plane_v3_rho", "jet pT;#it{p}^{in-plane}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); @@ -348,30 +358,20 @@ struct JetChargedV2 { registry.add("h2_mcp_centrality_jet_pt_out_of_plane_v3_rho", "centrality vs #it{p}^{out-of-plane}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{120, -10.0, 110.0}, jetPtAxisRhoAreaSub}}); registry.add("h3_mcp_centrality_deltapT_RandomCornPhi_localrhovsphi", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}; #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); - registry.add("h3_mcp_centrality_deltapT_RandomCornPhi_rhorandomconewithoutleadingjet", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}; #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); - registry.add("h3_mcp_centrality_deltapT_RandomCornPhi_localrhovsphiwithoutleadingjet", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}(#varphi); #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); - - registry.add("h_mcColl_counts_areasub", " number of mc events; event status; entries", {HistType::kTH1F, {{10, 0, 10}}}); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(1, "allMcColl"); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(2, "vertexZ"); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(3, "noRecoColl"); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(4, "splitColl"); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(5, "recoEvtSel"); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(6, "centralitycut"); - registry.get(HIST("h_mcColl_counts_areasub"))->GetXaxis()->SetBinLabel(7, "occupancycut"); - registry.add("h_mcColl_rho", "mc collision rho;#rho (GeV/#it{c}); counts", {HistType::kTH1F, {{500, 0.0, 500.0}}}); - //< \sigma p_T at local rho test plot > - registry.add("h_accept_Track", "all and accept track;Track;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); - registry.get(HIST("h_accept_Track"))->GetXaxis()->SetBinLabel(1, "acceptTrk"); - registry.get(HIST("h_accept_Track"))->GetXaxis()->SetBinLabel(2, "acceptTrkInFit"); - registry.get(HIST("h_accept_Track"))->GetXaxis()->SetBinLabel(3, "beforeSumptFit"); - registry.get(HIST("h_accept_Track"))->GetXaxis()->SetBinLabel(4, "afterSumptFit"); - registry.get(HIST("h_accept_Track"))->GetXaxis()->SetBinLabel(5, "getNtrk"); - registry.get(HIST("h_accept_Track"))->GetXaxis()->SetBinLabel(6, "getNtrkMCP"); + registry.add("h_mcColl_counts", " number of mc events; event status; entries", {HistType::kTH1F, {{10, 0, 10}}}); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(1, "allMcColl"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(2, "vertexZ"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(3, "noRecoColl"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(4, "splitColl"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(5, "recoEvtSel"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(6, "centralitycut"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(7, "occupancycut"); + registry.add("h_mcColl_rho", "mc collision rho;#rho (GeV/#it{c}); counts", {HistType::kTH1F, {{500, 0.0, 500.0}}}); + registry.add("h_mc_zvertex", "position of collision ;#it{Z} (cm)", {HistType::kTH1F, {{300, -15.0, 15.0}}}); } - if (doprocessJetsMatchedSubtracted) { + if (doprocessJetsMatched) { registry.add("h_mc_collisions_matched", "mc collisions status;event status;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}); registry.add("h_mcd_events_matched", "mcd event status;event status;entries", {HistType::kTH1F, {{6, 0.0, 6.0}}}); registry.add("h_mc_rho_matched", "mc collision rho;#rho (GeV/#it{c}); counts", {HistType::kTH1F, {{500, -100.0, 500.0}}}); @@ -522,8 +522,9 @@ struct JetChargedV2 { registry.fill(HIST("leadJetEtaMCP"), leadingJetEta); } - template - void fitFncMCP(U const& collision, T const& tracks, J const& jets, TH1F* hPtsumSumptFitMCP, double leadingJetEta, bool mcLevelIsParticleLevel, float weight = 1.0) + // Run General_Purpose MC MCP + template + void fitFncAreaSubMCP(U const& collision, J const& jets, TH1F* hPtsumSumptFitMCP, bool mcLevelIsParticleLevel, float weight = 1.0) { double ep2 = 0.; double ep3 = 0.; @@ -571,7 +572,6 @@ struct JetChargedV2 { hPtsumSumptFitMCP->Fit(fFitModulationV2v3P, "Q", "ep", 0, o2::constants::math::TwoPI); - // int paraNum = 5; double temppara[5]; temppara[0] = fFitModulationV2v3P->GetParameter(0); temppara[1] = fFitModulationV2v3P->GetParameter(1); @@ -640,65 +640,87 @@ struct JetChargedV2 { } } } - // RCpT - for (uint i = 0; i < cfgnMods->size(); i++) { - TRandom3 randomNumber(0); - float randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); - float randomConePhi = randomNumber.Uniform(0.0, o2::constants::math::TwoPI); - float randomConePt = 0; - double integralValueRC = fFitModulationV2v3P->Integral(randomConePhi - randomConeR, randomConePhi + randomConeR); - double rholocalRC = collision.rho() / (2 * randomConeR * temppara[0]) * integralValueRC; + } + // Run jet-jet MC MCP leading jet fill + template + void fitFncMCP(U const& collision, J const& jets, bool mcLevelIsParticleLevel, float weight = 1.0) + { + double ep2 = 0.; + double ep3 = 0.; + int cfgNmodA = 2; + int cfgNmodB = 3; + int evtPlnAngleA = 7; + int evtPlnAngleB = 3; + int evtPlnAngleC = 5; + for (uint i = 0; i < cfgnMods->size(); i++) { int nmode = cfgnMods->at(i); + int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); if (nmode == cfgNmodA) { - double rcPhiPsi2; - rcPhiPsi2 = randomConePhi - ep2; + if (collision.qvecAmp()[detId] > collQvecAmpDetId) { + ep2 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode); + } + } else if (nmode == cfgNmodB) { + if (collision.qvecAmp()[detId] > collQvecAmpDetId) { + ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode); + } + } + } + registry.fill(HIST("h_mcp_evtnum_centrlity"), evtnum, collision.centFT0M()); + registry.fill(HIST("h_ep2_evtnum"), evtnum, ep2); + registry.fill(HIST("h_ep3_evtnum"), evtnum, ep3); - for (auto const& track : tracks) { - if (jetderiveddatautilities::selectTrack(track, trackSelection)) { - float dPhi = RecoDecay::constrainAngle(track.phi() - randomConePhi, static_cast(-o2::constants::math::PI)); - float dEta = track.eta() - randomConeEta; - if (std::sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { - randomConePt += track.pt(); - } - } + for (uint i = 0; i < cfgnMods->size(); i++) { + int nmode = cfgnMods->at(i); + int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet, mcLevelIsParticleLevel)) { + continue; + } + if (jet.r() != round(selectedJetsRadius * 100.0f)) { + continue; } - registry.fill(HIST("h3_mcp_centrality_deltapT_RandomCornPhi_localrhovsphi"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * rholocalRC, rcPhiPsi2, weight); - // removing the leading jet from the random cone - if (jets.size() > 0) { // if there are no jets in the acceptance (from the jetfinder cuts) then there can be no leading jet - float dPhiLeadingJet = RecoDecay::constrainAngle(jets.iteratorAt(0).phi() - randomConePhi, static_cast(-o2::constants::math::PI)); - float dEtaLeadingJet = jets.iteratorAt(0).eta() - randomConeEta; + if (nmode == cfgNmodA) { + registry.fill(HIST("h_mcp_jet_pt_rhoareasubtracted"), jet.pt(), weight); - bool jetWasInCone = false; - while ((randomConeLeadJetDeltaR <= 0 && (std::sqrt(dEtaLeadingJet * dEtaLeadingJet + dPhiLeadingJet * dPhiLeadingJet) < jets.iteratorAt(0).r() / 100.0 + randomConeR)) || (randomConeLeadJetDeltaR > 0 && (std::sqrt(dEtaLeadingJet * dEtaLeadingJet + dPhiLeadingJet * dPhiLeadingJet) < randomConeLeadJetDeltaR))) { - jetWasInCone = true; - randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); - randomConePhi = randomNumber.Uniform(0.0, o2::constants::math::TwoPI); - dPhiLeadingJet = RecoDecay::constrainAngle(jets.iteratorAt(0).phi() - randomConePhi, static_cast(-o2::constants::math::PI)); - dEtaLeadingJet = jets.iteratorAt(0).eta() - randomConeEta; + double phiMinusPsi2; + if (collision.qvecAmp()[detId] < collQvecAmpDetId) { + continue; } - if (jetWasInCone) { - randomConePt = 0.0; - for (auto const& track : tracks) { - if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > randomConeR)) { // if track selection is uniformTrack, dcaXY and dcaZ cuts need to be added as they aren't in the selection so that they can be studied here - float dPhi = RecoDecay::constrainAngle(track.phi() - randomConePhi, static_cast(-o2::constants::math::PI)); - float dEta = track.eta() - randomConeEta; - if (std::sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { - randomConePt += track.pt(); - } - } - } + phiMinusPsi2 = jet.phi() - ep2; + if ((phiMinusPsi2 < o2::constants::math::PIQuarter) || (phiMinusPsi2 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (phiMinusPsi2 >= evtPlnAngleB * o2::constants::math::PIQuarter && phiMinusPsi2 < evtPlnAngleC * o2::constants::math::PIQuarter)) { + registry.fill(HIST("h_mcp_jet_pt_in_plane_v2_rho"), jet.pt(), weight); + registry.fill(HIST("h2_mcp_centrality_jet_pt_in_plane_v2_rho"), collision.centFT0M(), jet.pt(), weight); + } else { + registry.fill(HIST("h_mcp_jet_pt_out_of_plane_v2_rho"), jet.pt(), weight); + registry.fill(HIST("h2_mcp_centrality_jet_pt_out_of_plane_v2_rho"), collision.centFT0M(), jet.pt(), weight); + } + } else if (nmode == cfgNmodB) { + double phiMinusPsi3; + if (collision.qvecAmp()[detId] < collQvecAmpDetId) { + continue; + } + ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); + phiMinusPsi3 = jet.phi() - ep3; + + if ((phiMinusPsi3 < o2::constants::math::PIQuarter) || (phiMinusPsi3 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (phiMinusPsi3 >= evtPlnAngleB * o2::constants::math::PIQuarter && phiMinusPsi3 < evtPlnAngleC * o2::constants::math::PIQuarter)) { + registry.fill(HIST("h_mcp_jet_pt_in_plane_v3_rho"), jet.pt(), weight); + registry.fill(HIST("h2_mcp_centrality_jet_pt_in_plane_v3_rho"), collision.centFT0M(), jet.pt(), weight); + } else { + registry.fill(HIST("h_mcp_jet_pt_out_of_plane_v3_rho"), jet.pt(), weight); + registry.fill(HIST("h2_mcp_centrality_jet_pt_out_of_plane_v3_rho"), collision.centFT0M(), jet.pt(), weight); } } - registry.fill(HIST("h3_mcp_centrality_deltapT_RandomCornPhi_localrhovsphiwithoutleadingjet"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * rholocalRC, rcPhiPsi2, weight); - registry.fill(HIST("h3_mcp_centrality_deltapT_RandomCornPhi_rhorandomconewithoutleadingjet"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * collision.rho(), rcPhiPsi2, weight); - } else if (nmode == cfgNmodB) { - continue; } } } + // Run General_Purpose MC MCP template void fillMCPAreaSubHistograms(TJets const& jet, float rho = 0.0, float weight = 1.0) { @@ -717,6 +739,22 @@ struct JetChargedV2 { } } + // Run jet-jet MC MCP + template + void fillMCPHistograms(TJets const& jet, float weight = 1.0) + { + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { + // fill mcp jet histograms + registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); + registry.fill(HIST("h_jet_eta_part"), jet.eta(), weight); + registry.fill(HIST("h_jet_phi_part"), jet.phi(), weight); + } + } + template void fillTrackHistograms(TTracks const& track, float weight = 1.0) { @@ -725,7 +763,7 @@ struct JetChargedV2 { } template - void fillGeoMatchedCorrHistograms(TBase const& jetMCD, TF1* fFitModulationRM, float tempparaA, double ep2, float rho, float mcrho = 0.0, float weight = 1.0) + void fillGeoMatchedCorrHistograms(TBase const& jetMCD, TF1* fFitModulationRM, float tempparaA, double ep2, float rho, bool subtractMCPBackground, float mcrho, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jetMCD.pt() > pTHatMaxMCD * pTHat) { @@ -742,8 +780,15 @@ struct JetChargedV2 { int evtPlnAngleC = 5; double integralValue = fFitModulationRM->Integral(jetMCD.phi() - jetRadius, jetMCD.phi() + jetRadius); double rholocal = rho / (2 * jetRadius * tempparaA) * integralValue; - double corrTagjetpt = jetMCP.pt() - (mcrho * jetMCP.area()); double corrBasejetpt = jetMCD.pt() - (rholocal * jetMCD.area()); + double corrTagjetpt; + if (subtractMCPBackground) { + double integralValueMCP = fFitModulationRM->Integral(jetMCP.phi() - jetRadius, jetMCP.phi() + jetRadius); + double rholocalMCP = mcrho / (2 * jetRadius * tempparaA) * integralValueMCP; + corrTagjetpt = jetMCP.pt() - (rholocalMCP * jetMCP.area()); + } else { + corrTagjetpt = jetMCP.pt(); + } double dcorrpt = corrTagjetpt - corrBasejetpt; double phiMinusPsi2 = jetMCD.phi() - ep2; if (jetfindingutilities::isInEtaAcceptance(jetMCD, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -1014,7 +1059,7 @@ struct JetChargedV2 { return; } registry.fill(HIST("h_collisions"), 2.5); - + registry.fill(HIST("h_collisions_Zvertex"), collision.posZ()); double leadingJetPt = -1; double leadingJetPhi = -1; double leadingJetEta = -1; @@ -1501,28 +1546,28 @@ struct JetChargedV2 { } PROCESS_SWITCH(JetChargedV2, processSigmaPtMCD, "jet spectra with rho-area subtraction for MCD", false); - void processSigmaPtMCP(McParticleCollision::iterator const& mccollision, - soa::SmallGroups> const& collisions, - soa::Join const& jets, - aod::JetTracks const& tracks, - aod::JetParticles const&) + void processSigmaPtAreaSubMCP(McParticleCollision::iterator const& mccollision, + soa::SmallGroups> const& collisions, + soa::Join const& jets, + aod::JetTracks const& tracks, + aod::JetParticles const&) { bool mcLevelIsParticleLevel = true; int acceptSplitCollInMCP = 2; - registry.fill(HIST("h_mcColl_counts_areasub"), 0.5); + registry.fill(HIST("h_mcColl_counts"), 0.5); if (std::abs(mccollision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_mcColl_counts_areasub"), 1.5); + registry.fill(HIST("h_mcColl_counts"), 1.5); if (collisions.size() < 1) { return; } - registry.fill(HIST("h_mcColl_counts_areasub"), 2.5); + registry.fill(HIST("h_mcColl_counts"), 2.5); if (acceptSplitCollisions == 0 && collisions.size() > 1) { return; } - registry.fill(HIST("h_mcColl_counts_areasub"), 3.5); + registry.fill(HIST("h_mcColl_counts"), 3.5); bool hasSel8Coll = false; bool centralityIsGood = false; @@ -1553,19 +1598,19 @@ struct JetChargedV2 { if (!hasSel8Coll) { return; } - registry.fill(HIST("h_mcColl_counts_areasub"), 4.5); + registry.fill(HIST("h_mcColl_counts"), 4.5); if (!centralityIsGood) { return; } - registry.fill(HIST("h_mcColl_counts_areasub"), 5.5); + registry.fill(HIST("h_mcColl_counts"), 5.5); if (!occupancyIsGood) { return; } - registry.fill(HIST("h_mcColl_counts_areasub"), 6.5); + registry.fill(HIST("h_mcColl_counts"), 6.5); registry.fill(HIST("h_mcColl_rho"), mccollision.rho()); - + registry.fill(HIST("h_mc_zvertex"), mccollision.posZ()); for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; @@ -1603,20 +1648,99 @@ struct JetChargedV2 { } } } - fitFncMCP(collision, tracks, jets, hPtsumSumptFitMCP, leadingJetEta, mcLevelIsParticleLevel); + fitFncAreaSubMCP(collision, jets, hPtsumSumptFitMCP, mcLevelIsParticleLevel); } delete hPtsumSumptFitMCP; delete fFitModulationV2v3P; evtnum += 1; } + PROCESS_SWITCH(JetChargedV2, processSigmaPtAreaSubMCP, "jet spectra with area-based subtraction for MC particle level", false); + + void processSigmaPtMCP(aod::JMcCollisions::iterator const& mccollision, + soa::SmallGroups> const& collisions, + soa::Join const& jets, + aod::JetParticles const&) + { + bool mcLevelIsParticleLevel = true; + int acceptSplitCollInMCP = 2; + + registry.fill(HIST("h_mcColl_counts"), 0.5); + if (std::abs(mccollision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("h_mcColl_counts"), 1.5); + if (collisions.size() < 1) { + return; + } + registry.fill(HIST("h_mcColl_counts"), 2.5); + if (acceptSplitCollisions == 0 && collisions.size() > 1) { + return; + } + registry.fill(HIST("h_mcColl_counts"), 3.5); + + bool hasSel8Coll = false; + bool centralityIsGood = false; + bool occupancyIsGood = false; + if (acceptSplitCollisions == acceptSplitCollInMCP) { + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { + hasSel8Coll = true; + } + if ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax)) { + centralityIsGood = true; + } + if ((trackOccupancyInTimeRangeMin < collisions.begin().trackOccupancyInTimeRange()) && (collisions.begin().trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMax)) { + occupancyIsGood = true; + } + } else { + for (auto const& collision : collisions) { + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { + hasSel8Coll = true; + } + if ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax)) { + centralityIsGood = true; + } + if ((trackOccupancyInTimeRangeMin < collision.trackOccupancyInTimeRange()) && (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMax)) { + occupancyIsGood = true; + } + } + } + if (!hasSel8Coll) { + return; + } + registry.fill(HIST("h_mcColl_counts"), 4.5); + + if (!centralityIsGood) { + return; + } + registry.fill(HIST("h_mcColl_counts"), 5.5); + + if (!occupancyIsGood) { + return; + } + registry.fill(HIST("h_mcColl_counts"), 6.5); + registry.fill(HIST("h_mc_zvertex"), mccollision.posZ()); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet, mcLevelIsParticleLevel)) { + continue; + } + fillMCPHistograms(jet); + } + for (auto const& collision : collisions) { + fitFncMCP(collision, jets, mcLevelIsParticleLevel); + } + evtnum += 1; + } PROCESS_SWITCH(JetChargedV2, processSigmaPtMCP, "jet spectra with area-based subtraction for MC particle level", false); - void processJetsMatchedSubtracted(McParticleCollision::iterator const& mccollision, - soa::SmallGroups> const& collisions, - ChargedMCDMatchedJets const& mcdjets, - ChargedMCPMatchedJets const&, - aod::JetTracks const& tracks, aod::JetParticles const&) + void processJetsMatched(McParticleCollision::iterator const& mccollision, + soa::SmallGroups> const& collisions, + ChargedMCDMatchedJets const& mcdjets, + ChargedMCPMatchedJets const&, + aod::JetTracks const& tracks, aod::JetParticles const&) { registry.fill(HIST("h_mc_collisions_matched"), 0.5); if (mccollision.size() < 1) { @@ -1728,14 +1852,14 @@ struct JetChargedV2 { return; } - fillGeoMatchedCorrHistograms(mcdjet, fFitModulationRM, tempparaA, ep2, collision.rho(), mcrho); + fillGeoMatchedCorrHistograms(mcdjet, fFitModulationRM, tempparaA, ep2, collision.rho(), subtractMCPBackground, collision.rho()); delete hPtsumSumptFitRM; delete fFitModulationRM; evtnum += 1; } } } - PROCESS_SWITCH(JetChargedV2, processJetsMatchedSubtracted, "matched mcp and mcd jets after subtraction", false); + PROCESS_SWITCH(JetChargedV2, processJetsMatched, "matched mcp and mcd jets", false); void processTracksQA(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks) diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index d327fa277b6..81e2ae5893d 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -81,8 +81,7 @@ struct JetHadronRecoil { Configurable triggerMasks{"triggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"}; Configurable outlierRejectEvent{"outlierRejectEvent", true, "where outliers are found, reject event (true) or just reject the single track/jet (false)"}; - - Preslice> partJetsPerCollision = aod::jet::mcCollisionId; + Configurable doSumw{"doSumw", false, "enable sumw2 for weighted histograms"}; TRandom3* rand = new TRandom3(0); @@ -119,68 +118,7 @@ struct JetHadronRecoil { AxisSpec dRAxisDet = {dRBinning, "#Delta R_{det}"}; AxisSpec dRAxisPart = {dRBinning, "#Delta R_{part}"}; - HistogramRegistry registry{"registry", - {{"hNtrig", "number of triggers;trigger type;entries", {HistType::kTH1F, {{2, 0, 2}}}}, - {"hSignalTriggersPtHard", "Signal triggers vs PtHard", {HistType::kTH1F, {{20, 0, 5}}}}, - {"hReferenceTriggersPtHard", "Reference triggers vs PtHard", {HistType::kTH1F, {{20, 0, 5}}}}, - {"hZvtxSelected", "Z vertex position;Z_{vtx};entries", {HistType::kTH1F, {{80, -20, 20}}}}, - {"hPtTrack", "Track p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}}, - {"hEtaTrack", "Track #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, - {"hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, - {"hTrack3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, - {"hPtTrackPtHard", "Tracks vs pThard;#frac{p_{T}}{#hat{p}};p_{T}", {HistType::kTH2F, {{20, 0, 5}, {200, 0, 200}}}}, - {"hConstituents3D", "3D constituents histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, - {"hReferencePtDPhi", "jet p_{T} vs DPhi;#Delta#phi;p_{T,jet}", {HistType::kTH2F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}}}}, - {"hReferencePtDPhiShifts", "rho shifts;#Delta#phi;p_{T,jet};shifts", {HistType::kTH3F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}, {20, 0.0, 2.0}}}}, - {"hSignalPtDPhi", "jet p_{T} vs DPhi;#Delta#phi;p_{T,jet}", {HistType::kTH2F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}}}}, - {"hReferencePt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{500, -100, 400}}}}, - {"hSignalPt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{500, -100, 400}}}}, - {"hSignalTriggers", "trigger p_{T};p_{T,trig};entries", {HistType::kTH1F, {{150, 0, 150}}}}, - {"hSignalPtHard", "jet p_{T} vs #hat{p};p_{T,jet};#frac{p_{T,trig}}{#hat{p}}", {HistType::kTH2F, {{500, -100, 400}, {20, 0, 5}}}}, - {"hReferenceTriggers", "trigger p_{T};p_{T,trig};entries", {HistType::kTH1F, {{150, 0, 150}}}}, - {"hReferencePtHard", "jet p_{T} vs #hat{p};p_{T,jet};#frac{p_{T,trig}}{#hat{p}}", {HistType::kTH2F, {{500, -100, 400}, {20, 0, 5}}}}, - {"hSigEventTriggers", "N_{triggers};events", {HistType::kTH1F, {{10, 0, 10}}}}, - {"hRefEventTriggers", "N_{triggers};events", {HistType::kTH1F, {{10, 0, 10}}}}, - {"hJetPt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{500, -100, 400}}}}, - {"hJetEta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, - {"hJetPhi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, - {"hJet3D", "3D jet distribution;p_{T};#eta;#phi", {HistType::kTH3F, {{500, -100, 400}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, - {"hTracksvsJets", "comparing leading tracks and jets;p_{T,track};p_{T,jet};#hat{p}", {HistType::kTH3F, {{200, 0, 200}, {500, -100, 400}, {195, 5, 200}}}}, - {"hPartvsJets", "comparing leading particles and jets;p_{T,part};p_{T,jet};#hat{p}", {HistType::kTH3F, {{200, 0, 200}, {500, -100, 400}, {195, 5, 200}}}}, - {"hPtPart", "Particle p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}}, - {"hEtaPart", "Particle #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, - {"hPhiPart", "Particle #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, - {"hPart3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, - {"hPtPartPtHard", "Track p_{T} vs #hat{p};p_{T};#frac{p_{T}}{#hat{p}}", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}}, - {"hDeltaR", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, - {"hDeltaRPart", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, - {"hDeltaRpT", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}}, - {"hDeltaRpTPart", "Particle jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{400, 0, 400}, dRAxis}}}, - {"hRhoSignal", "Signal Rho bkg;#rho;entries", {HistType::kTH1F, {{220, 0, 220}}}}, - {"hRhoReference", "Reference Rho bkg;#rho;entries", {HistType::kTH1F, {{220, 0, 220}}}}, - {"hRhoReferenceShift", "Testing reference shifts;#rho;shift", {HistType::kTH2F, {{220, 0, 220}, {20, 0.0, 2.0}}}}, - {"hDeltaRSignal", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, - {"hDeltaRSignalPart", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, - {"hDeltaRpTSignal", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}}, - {"hDeltaRpTSignalPart", "Particle jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{400, 0, 400}, dRAxis}}}, - {"hDeltaRpTDPhiSignal", "jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{500, -100, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}}, - {"hDeltaRpTDPhiSignalPart", "Particle jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{400, 0, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}}, - {"hDeltaRReference", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, - {"hDeltaRPartReference", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, - {"hDeltaRpTReference", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}}, - {"hDeltaRpTPartReference", "Particle jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{400, 0, 400}, dRAxis}}}, - {"hDeltaRpTDPhiReference", "jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{500, -100, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}}, - {"hDeltaRpTDPhiReferenceShifts", "testing shifts;p_{T,jet};#Delta#phi;#DeltaR;shifts", {HistType::kTHnSparseD, {{500, -100, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis, {20, 0.0, 2.0}}}}, - {"hDeltaRpTDPhiReferencePart", "jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{400, 0, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}}, - {"hPtMatched", "p_{T} matching;p_{T,det};p_{T,part}", {HistType::kTH2F, {{500, -100, 400}, {400, 0, 400}}}}, - {"hPhiMatched", "#phi matching;#phi_{det};#phi_{part}", {HistType::kTH2F, {{100, 0.0, o2::constants::math::TwoPI}, {100, 0.0, o2::constants::math::TwoPI}}}}, - {"hDeltaRMatched", "#DeltaR matching;#DeltaR_{det};#DeltaR_{part}", {HistType::kTH2F, {dRAxisDet, dRAxisPart}}}, - {"hPtMatched1d", "p_{T} matching 1d;p_{T,part}", {HistType::kTH1F, {{400, 0, 400}}}}, - {"hDeltaRMatched1d", "#DeltaR matching 1d;#DeltaR_{part}", {HistType::kTH1F, {dRAxisPart}}}, - {"hPtResolution", "p_{T} resolution;p_{T,part};Relative Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -5.0, 5.0}}}}, - {"hPhiResolution", "#phi resolution;#p_{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -7.0, 7.0}}}}, - {"hDeltaRResolution", "#DeltaR Resolution;p_{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -0.15, 0.15}}}}, - {"hFullMatching", "Full 6D matching;p_{T,det};p_{T,part};#phi_{det};#phi_{part};#DeltaR_{det};#DeltaR_{part}", {HistType::kTHnSparseD, {ptAxisDet, ptAxisPart, phiAxisDet, phiAxisPart, dRAxisDet, dRAxisPart}}}}}; + HistogramRegistry registry; std::vector eventSelectionBits; int trackSelection = -1; @@ -194,15 +132,84 @@ struct JetHadronRecoil { trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); - Filter jetCuts = aod::jet::r == nround(jetR.node() * 100.0f); - Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); - Filter particleCuts = (aod::jmcparticle::pt >= trackPtMin && aod::jmcparticle::pt < trackPtMax && aod::jmcparticle::eta > trackEtaMin && aod::jmcparticle::eta < trackEtaMax); - Filter eventTrackLevelCuts = nabs(aod::jcollision::posZ) < vertexZCut; - jetReclusterer.isReclustering = true; jetReclusterer.algorithm = fastjet::JetAlgorithm::cambridge_algorithm; jetReclusterer.jetR = 2 * jetR; jetReclusterer.recombScheme = fastjet::WTA_pt_scheme; + + registry.add("hZvtxSelected", "Z vertex position;Z_{vtx};entries", {HistType::kTH1F, {{80, -20, 20}}}, doSumw); + + if (doprocessData || doprocessDataWithRhoSubtraction || doprocessMCD || doprocessMCDWithRhoSubtraction || doprocessMCDWeighted || doprocessMCDWeightedWithRhoSubtraction || doprocessMCP || doprocessMCPWeighted) { + registry.add("hNtrig", "number of triggers;trigger type;entries", {HistType::kTH1F, {{2, 0, 2}}}, doSumw); + registry.add("hSignalTriggersPtHard", "Signal triggers vs PtHard", {HistType::kTH1F, {{20, 0, 5}}}, doSumw); + registry.add("hReferenceTriggersPtHard", "Reference triggers vs PtHard", {HistType::kTH1F, {{20, 0, 5}}}, doSumw); + registry.add("hConstituents3D", "3D constituents histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hReferencePtDPhi", "jet p_{T} vs DPhi;#Delta#phi;p_{T,jet}", {HistType::kTH2F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}}}, doSumw); + registry.add("hReferencePtDPhiShifts", "rho shifts;#Delta#phi;p_{T,jet};shifts", {HistType::kTH3F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}, {20, 0.0, 2.0}}}, doSumw); + registry.add("hSignalPtDPhi", "jet p_{T} vs DPhi;#Delta#phi;p_{T,jet}", {HistType::kTH2F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}}}, doSumw); + registry.add("hReferencePt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{500, -100, 400}}}, doSumw); + registry.add("hSignalPt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{500, -100, 400}}}, doSumw); + registry.add("hSignalTriggers", "trigger p_{T};p_{T,trig};entries", {HistType::kTH1F, {{150, 0, 150}}}, doSumw); + registry.add("hSignalPtHard", "jet p_{T} vs #hat{p};p_{T,jet};#frac{p_{T,trig}}{#hat{p}}", {HistType::kTH2F, {{500, -100, 400}, {20, 0, 5}}}, doSumw); + registry.add("hReferenceTriggers", "trigger p_{T};p_{T,trig};entries", {HistType::kTH1F, {{150, 0, 150}}}, doSumw); + registry.add("hReferencePtHard", "jet p_{T} vs #hat{p};p_{T,jet};#frac{p_{T,trig}}{#hat{p}}", {HistType::kTH2F, {{500, -100, 400}, {20, 0, 5}}}, doSumw); + registry.add("hSigEventTriggers", "N_{triggers};events", {HistType::kTH1F, {{10, 0, 10}}}, doSumw); + registry.add("hRefEventTriggers", "N_{triggers};events", {HistType::kTH1F, {{10, 0, 10}}}, doSumw); + registry.add("hJetPt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{500, -100, 400}}}, doSumw); + registry.add("hJetEta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}, doSumw); + registry.add("hJetPhi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hJet3D", "3D jet distribution;p_{T};#eta;#phi", {HistType::kTH3F, {{500, -100, 400}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + } + + if (doprocessData || doprocessDataWithRhoSubtraction || doprocessMCD || doprocessMCDWithRhoSubtraction || doprocessMCDWeighted || doprocessMCDWeightedWithRhoSubtraction) { + registry.add("hPtTrack", "Track p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}, doSumw); + registry.add("hEtaTrack", "Track #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}, doSumw); + registry.add("hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hTrack3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hPtTrackPtHard", "Tracks vs pThard;#frac{p_{T}}{#hat{p}};p_{T}", {HistType::kTH2F, {{20, 0, 5}, {200, 0, 200}}}, doSumw); + registry.add("hTracksvsJets", "comparing leading tracks and jets;p_{T,track};p_{T,jet};#hat{p}", {HistType::kTH3F, {{200, 0, 200}, {500, -100, 400}, {195, 5, 200}}}, doSumw); + registry.add("hDeltaR", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}, doSumw); + registry.add("hDeltaRpT", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}, doSumw); + registry.add("hRhoSignal", "Signal Rho bkg;#rho;entries", {HistType::kTH1F, {{220, 0, 220}}}, doSumw); + registry.add("hRhoReference", "Reference Rho bkg;#rho;entries", {HistType::kTH1F, {{220, 0, 220}}}, doSumw); + registry.add("hRhoReferenceShift", "Testing reference shifts;#rho;shift", {HistType::kTH2F, {{220, 0, 220}, {20, 0.0, 2.0}}}, doSumw); + registry.add("hDeltaRSignal", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}, doSumw); + registry.add("hDeltaRpTSignal", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}, doSumw); + registry.add("hDeltaRpTDPhiSignal", "jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{500, -100, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}, doSumw); + registry.add("hDeltaRReference", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}, doSumw); + registry.add("hDeltaRpTReference", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}, doSumw); + registry.add("hDeltaRpTDPhiReference", "jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{500, -100, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}, doSumw); + registry.add("hDeltaRpTDPhiReferenceShifts", "testing shifts;p_{T,jet};#Delta#phi;#DeltaR;shifts", {HistType::kTHnSparseD, {{500, -100, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis, {20, 0.0, 2.0}}}, doSumw); + } + + if (doprocessMCP || doprocessMCPWeighted) { + registry.add("hPartvsJets", "comparing leading particles and jets;p_{T,part};p_{T,jet};#hat{p}", {HistType::kTH3F, {{200, 0, 200}, {500, -100, 400}, {195, 5, 200}}}, doSumw); + registry.add("hPtPart", "Particle p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}, doSumw); + registry.add("hEtaPart", "Particle #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}, doSumw); + registry.add("hPhiPart", "Particle #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hPart3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hPtPartPtHard", "Track p_{T} vs #hat{p};p_{T};#frac{p_{T}}{#hat{p}}", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}, doSumw); + registry.add("hDeltaRPart", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}, doSumw); + registry.add("hDeltaRpTPart", "Particle jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{400, 0, 400}, dRAxis}}, doSumw); + registry.add("hDeltaRSignalPart", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}, doSumw); + registry.add("hDeltaRpTSignalPart", "Particle jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{400, 0, 400}, dRAxis}}, doSumw); + registry.add("hDeltaRpTDPhiSignalPart", "Particle jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{400, 0, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}, doSumw); + registry.add("hDeltaRPartReference", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}, doSumw); + registry.add("hDeltaRpTPartReference", "Particle jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{400, 0, 400}, dRAxis}}, doSumw); + registry.add("hDeltaRpTDPhiReferencePart", "jet p_{T} vs #DeltaR vs #Delta#phi;p_{T,jet};#Delta#phi;#DeltaR", {HistType::kTH3F, {{400, 0, 400}, {100, 0, o2::constants::math::TwoPI}, dRAxis}}, doSumw); + } + + if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWithRhoSubtraction || doprocessJetsMCPMCDMatchedWeighted || doprocessJetsMCPMCDMatchedWeightedWithRhoSubtraction || doprocessRecoilJetsMCPMCDMatched || doprocessRecoilJetsMCPMCDMatchedWeighted) { + registry.add("hPtMatched", "p_{T} matching;p_{T,det};p_{T,part}", {HistType::kTH2F, {{500, -100, 400}, {400, 0, 400}}}, doSumw); + registry.add("hPhiMatched", "#phi matching;#phi_{det};#phi_{part}", {HistType::kTH2F, {{100, 0.0, o2::constants::math::TwoPI}, {100, 0.0, o2::constants::math::TwoPI}}}, doSumw); + registry.add("hDeltaRMatched", "#DeltaR matching;#DeltaR_{det};#DeltaR_{part}", {HistType::kTH2F, {dRAxisDet, dRAxisPart}}, doSumw); + registry.add("hPtMatched1d", "p_{T} matching 1d;p_{T,part}", {HistType::kTH1F, {{400, 0, 400}}}, doSumw); + registry.add("hDeltaRMatched1d", "#DeltaR matching 1d;#DeltaR_{part}", {HistType::kTH1F, {dRAxisPart}}, doSumw); + registry.add("hPtResolution", "p_{T} resolution;p_{T,part};Relative Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -5.0, 5.0}}}, doSumw); + registry.add("hPhiResolution", "#phi resolution;#p_{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -7.0, 7.0}}}, doSumw); + registry.add("hDeltaRResolution", "#DeltaR Resolution;p_{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -0.15, 0.15}}}, doSumw); + registry.add("hFullMatching", "Full 6D matching;p_{T,det};p_{T,part};#phi_{det};#phi_{part};#DeltaR_{det};#DeltaR_{part}", {HistType::kTHnSparseD, {ptAxisDet, ptAxisPart, phiAxisDet, phiAxisPart, dRAxisDet, dRAxisPart}}, doSumw); + } } template @@ -597,7 +604,7 @@ struct JetHadronRecoil { } void processData(soa::Filtered::iterator const& collision, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -612,7 +619,7 @@ struct JetHadronRecoil { PROCESS_SWITCH(JetHadronRecoil, processData, "process data", true); void processDataWithRhoSubtraction(soa::Filtered>::iterator const& collision, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -628,7 +635,7 @@ struct JetHadronRecoil { void processMCD(soa::Filtered>::iterator const& collision, aod::JMcCollisions const&, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -650,7 +657,7 @@ struct JetHadronRecoil { void processMCDWithRhoSubtraction(soa::Filtered>::iterator const& collision, aod::JMcCollisions const&, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -672,7 +679,7 @@ struct JetHadronRecoil { void processMCDWeighted(soa::Filtered>::iterator const& collision, aod::JMcCollisions const&, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -694,7 +701,7 @@ struct JetHadronRecoil { void processMCDWeightedWithRhoSubtraction(soa::Filtered>::iterator const& collision, aod::JMcCollisions const&, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -715,7 +722,7 @@ struct JetHadronRecoil { PROCESS_SWITCH(JetHadronRecoil, processMCDWeightedWithRhoSubtraction, "process MC detector level with event weights and rho subtraction", false); void processMCP(aod::JetMcCollision const& collision, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& particles) { if (std::abs(collision.posZ()) > vertexZCut) { @@ -733,7 +740,7 @@ struct JetHadronRecoil { PROCESS_SWITCH(JetHadronRecoil, processMCP, "process MC particle level", false); void processMCPWeighted(aod::JetMcCollision const& collision, - soa::Filtered> const& jets, + soa::Filtered> const& jets, soa::Filtered const& particles) { if (std::abs(collision.posZ()) > vertexZCut) { @@ -893,9 +900,6 @@ struct JetHadronRecoil { deltaPhi = RecoDecay::constrainAngle(jet.phi() - jetReclustered[0].phi(), -o2::constants::math::PI); deltaY = jet.y() - jetReclustered[0].rap(); dR = RecoDecay::sqrtSumOfSquares(deltaPhi, deltaY); - LOG(debug) << "orig. jet n const = " << jet.tracksIds().size() << " pt = " << jet.pt() << " eta = " << jet.eta() << " phi = " << jet.phi(); - LOG(debug) << "recl. jet n const = " << clusterSeq.constituents(jetReclustered[0]).size() << " pt = " << jetReclustered[0].pt() << " eta = " << jetReclustered[0].eta() << " phi = " << jetReclustered[0].phi(); - LOG(debug) << "distance = " << dR; return dR; } }; diff --git a/PWGJE/Tasks/jetShape.cxx b/PWGJE/Tasks/jetShape.cxx index 9a7c857e256..58741ddd769 100644 --- a/PWGJE/Tasks/jetShape.cxx +++ b/PWGJE/Tasks/jetShape.cxx @@ -260,7 +260,7 @@ struct JetShapeTask { } PROCESS_SWITCH(JetShapeTask, processJetShape, "JetShape", true); - void processProductionRatio(soa::Filtered>::iterator const& collision, soa::Join const& tracks, soa::Join const& jets) + void processProductionRatio(soa::Filtered::iterator const& collision, soa::Join const& tracks, soa::Join const& jets) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { return; @@ -275,7 +275,6 @@ struct JetShapeTask { // tracks conditions for (const auto& track : tracks) { - registry.fill(HIST("trackTpcNClsCrossedRows"), track.tpcNClsCrossedRows()); registry.fill(HIST("trackDcaXY"), track.dcaXY()); registry.fill(HIST("trackItsChi2NCl"), track.itsChi2NCl()); diff --git a/PWGJE/Tasks/recoilJets.cxx b/PWGJE/Tasks/recoilJets.cxx index 286b0b5004c..27c6bc38aca 100644 --- a/PWGJE/Tasks/recoilJets.cxx +++ b/PWGJE/Tasks/recoilJets.cxx @@ -52,22 +52,18 @@ using namespace o2::framework::expressions; using FilteredColl = soa::Filtered>::iterator; using FilteredCollPartLevel = - soa::Filtered>::iterator; + soa::Filtered>::iterator; using FilteredCollDetLevelGetWeight = - soa::Filtered>::iterator; + soa::Filtered>::iterator; using FilteredEventMultiplicity = soa::Filtered>::iterator; using FilteredJets = soa::Filtered>; using FilteredJetsDetLevel = - soa::Filtered>; + soa::Filtered>; using FilteredJetsPartLevel = - soa::Filtered>; + soa::Filtered>; using FilteredMatchedJetsDetLevel = soa::Filtered evSel{"evSel", "sel8", "Choose event selection"}; - Configurable trkSel{"trkSel", "globalTracks", - "Set track selection"}; + Configurable trkSel{"trkSel", "globalTracks", "Set track selection"}; Configurable vertexZCut{"vertexZCut", 10., "Accepted z-vertex range"}; - Configurable fracSig{"fracSig", 0.9, - "Fraction of events to use for signal TT"}; + Configurable fracSig{"fracSig", 0.9, "Fraction of events to use for signal TT"}; - Configurable trkPtMin{"trkPtMin", 0.15, - "Minimum pT of acceptanced tracks"}; - Configurable trkPtMax{"trkPtMax", 100., - "Maximum pT of acceptanced tracks"}; + Configurable trkPtMin{"trkPtMin", 0.15, "Minimum pT of acceptanced tracks"}; + Configurable trkPtMax{"trkPtMax", 100., "Maximum pT of acceptanced tracks"}; Configurable trkEtaCut{"trkEtaCut", 0.9, "Eta acceptance of TPC"}; Configurable jetR{"jetR", 0.4, "Jet cone radius"}; - Configurable triggerMasks{"triggerMasks", "", - "Relevant trigger masks: fTrackLowPt,fTrackHighPt"}; + Configurable triggerMasks{"triggerMasks", "", "Relevant trigger masks: fTrackLowPt,fTrackHighPt"}; Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection " "applied at the jet finder level, here rejection is applied for " "collision and track process functions"}; - Configurable meanFT0A{"meanFT0A", -1.0, "Mean value of FT0A"}; - - Configurable meanFT0C{"meanFT0C", -1.0, "Mean value of FT0C"}; - - Configurable meanFT0M{"meanFT0M", -1.0, "Mean value of FT0M"}; + Configurable meanFT0A{"meanFT0A", -1., "Mean value of FT0A signal"}; + Configurable meanFT0C{"meanFT0C", -1., "Mean value of FT0C signal"}; // List of configurable parameters for MC - Configurable pTHatExponent{"pTHatExponent", 4.0, - "Exponent of the event weight for the calculation of pTHat"}; - Configurable pTHatMax{"pTHatMax", 999.0, - "Maximum fraction of hard scattering for jet acceptance in MC"}; + Configurable pTHatExponent{"pTHatExponent", 4.0, "Exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatMax{"pTHatMax", 999.0, "Maximum fraction of hard scattering for jet acceptance in MC"}; // Parameters for recoil jet selection - Configurable ptTTrefMin{"ptTTrefMin", 5., - "Minimum pT of reference TT"}; - Configurable ptTTrefMax{"ptTTrefMax", 7., - "Maximum pT of reference TT"}; + Configurable ptTTrefMin{"ptTTrefMin", 5., "Minimum pT of reference TT"}; + Configurable ptTTrefMax{"ptTTrefMax", 7., "Maximum pT of reference TT"}; Configurable ptTTsigMin{"ptTTsigMin", 20., "Minimum pT of signal TT"}; Configurable ptTTsigMax{"ptTTsigMax", 50., "Maximum pT of signal TT"}; - Configurable recoilRegion{"recoilRegion", 0.6, - "Width of recoil acceptance"}; + Configurable recoilRegion{"recoilRegion", 0.6, "Width of recoil acceptance"}; - Configurable maxJetConstituentPt{"maxJetConstituentPt", 100., - "Remove jets with constituent above this pt cut"}; + Configurable maxJetConstituentPt{"maxJetConstituentPt", 100., "Remove jets with constituent above this pT cut"}; // List of configurable parameters for histograms - Configurable histJetPt{"histJetPt", 100, - "Maximum value of jet pT shown in histograms"}; + Configurable histJetPt{"histJetPt", 100, "Maximum value of jet pT shown in histograms"}; + Configurable histMultBins{"histMultBins", 1000, "Number of bins for scaled FT0M multiplicity"}; // Axes specification - AxisSpec pT{histJetPt, 0.0, histJetPt * 1.0, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec jetPTcorr{histJetPt + 20, -20., histJetPt * 1.0, - "#it{p}_{T, jet}^{ch, corr} (GeV/#it{c})"}; + AxisSpec pT{histJetPt, 0.0, histJetPt * 1., "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec jetPTcorr{histJetPt + 20, -20., histJetPt * 1.0, "#it{p}_{T, jet}^{ch, corr} (GeV/#it{c})"}; AxisSpec phiAngle{40, 0.0, constants::math::TwoPI, "#it{#varphi} (rad)"}; - AxisSpec deltaPhiAngle{52, 0.0, constants::math::PI, - "#Delta#it{#varphi} (rad)"}; + AxisSpec deltaPhiAngle{52, 0.0, constants::math::PI, "#Delta#it{#varphi} (rad)"}; AxisSpec pseudorap{40, -1., 1., "#it{#eta}"}; AxisSpec pseudorapJets{20, -0.5, 0.5, "#it{#eta}_{jet}"}; AxisSpec jetArea{50, 0.0, 5., "Area_{jet}"}; AxisSpec rhoArea{60, 0.0, 60., "#it{#rho} #times Area_{jet}"}; AxisSpec rho{50, 0.0, 50., "#it{#rho}"}; + AxisSpec scaledFT0C{histMultBins, 0.0, 20., "FT0C / #LT FT0C #GT"}; + AxisSpec scaledFT0M{histMultBins, 0.0, 20., "FT0M^{*}"}; + ConfigurableAxis multFT0CThresh{"multFT0CThresh", {VARIABLE_WIDTH, 0, 0.2, 0.3, 0.4, 0.6, 0.8, 1., 1.4, 1.8, 2.4, 3.6, 5., 20.}, "Percentiles of scaled FT0C: 100-90%, 90-80%, 80-70%, 70-60%, 60-50%, 50-40%, 40-30%, 30-20%, 20-10%, 10-1%, 1-0.1%"}; // to adjust the boarders + ConfigurableAxis multFT0MThresh{"multFT0MThresh", {VARIABLE_WIDTH, 0, 0.2, 0.3, 0.4, 0.6, 0.8, 1., 1.4, 1.8, 2.4, 3.6, 5., 20.}, "Percentiles of scaled FT0M: 100-90%, 90-80%, 80-70%, 70-60%, 60-50%, 50-40%, 40-30%, 30-20%, 20-10%, 10-1%, 1-0.1%"}; - Preslice partJetsPerCollision = - aod::jet::mcCollisionId; - + // Auxiliary variables TRandom3* rand = new TRandom3(0); // Declare filter on collision Z vertex Filter collisionFilter = nabs(aod::jcollision::posZ) < vertexZCut; Filter collisionFilterMC = nabs(aod::jmccollision::posZ) < vertexZCut; - // Declare filters on accepted tracks and MC particles (settings for jet reco - // are provided in the jet finder wagon) - Filter trackFilter = aod::jtrack::pt > trkPtMin&& aod::jtrack::pt < - trkPtMax&& nabs(aod::jtrack::eta) < trkEtaCut; + // Declare filters on accepted tracks and MC particles (settings for jet reco are provided in the jet finder wagon) + Filter trackFilter = aod::jtrack::pt > trkPtMin&& aod::jtrack::pt < trkPtMax&& nabs(aod::jtrack::eta) < trkEtaCut; Filter partFilter = nabs(aod::jmcparticle::eta) < trkEtaCut; // Declare filter on jets @@ -171,280 +151,179 @@ struct RecoilJets { std::vector triggerMaskBits; Service pdg; + Preslice partJetsPerCollision = aod::jet::mcCollisionId; void init(InitContext const&) { std::string evSelToString = static_cast(evSel); std::string trkSelToString = static_cast(trkSel); - eventSelectionBits = - jetderiveddatautilities::initialiseEventSelectionBits(evSelToString); - trackSelection = - jetderiveddatautilities::initialiseTrackSelection(trkSelToString); - triggerMaskBits = - jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); + eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(evSelToString); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(trkSelToString); + triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); // List of raw and MC det. distributions if (doprocessData || doprocessMCDetLevel || doprocessMCDetLevelWeighted) { - spectra.add("hEventSelectionCount", "Count # of events in the analysis", - kTH1F, {{3, 0.0, 3.}}); - spectra.get(HIST("hEventSelectionCount")) - ->GetXaxis() - ->SetBinLabel(1, "Total # of events"); - spectra.get(HIST("hEventSelectionCount")) - ->GetXaxis() - ->SetBinLabel( - 2, Form("# of events after sel. %s", evSelToString.data())); - spectra.get(HIST("hEventSelectionCount")) - ->GetXaxis() - ->SetBinLabel(3, "# of events w. outlier"); - - spectra.add("vertexZ", "Z vertex of collisions", kTH1F, - {{60, -12., 12.}}); - spectra.add("hHasAssocMcCollision", - "Has det. level coll. associat. MC coll.", kTH1F, - {{2, 0.0, 2.}}); - spectra.get(HIST("hHasAssocMcCollision")) - ->GetXaxis() - ->SetBinLabel(1, "Yes"); - spectra.get(HIST("hHasAssocMcCollision")) - ->GetXaxis() - ->SetBinLabel(2, "No"); - - spectra.add("hTrackSelectionCount", "Count # of tracks in the analysis", - kTH1F, {{2, 0.0, 2.}}); - spectra.get(HIST("hTrackSelectionCount")) - ->GetXaxis() - ->SetBinLabel(1, "Total # of tracks"); - spectra.get(HIST("hTrackSelectionCount")) - ->GetXaxis() - ->SetBinLabel( - 2, Form("# of tracks after sel. %s", trkSelToString.data())); - - spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, - {pT, pseudorap, phiAngle}); - - spectra.add( - "hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, - {{40, 10., - 50.}}); // needed to distinguish merged data from diff. wagons - - spectra.add("hNtrig", "Total number of selected triggers per class", - kTH1F, {{2, 0.0, 2.}}); - spectra.get(HIST("hNtrig"))->GetXaxis()->SetBinLabel(1, "TT_{ref}"); - spectra.get(HIST("hNtrig"))->GetXaxis()->SetBinLabel(2, "TT_{sig}"); - - spectra.add("hTTRef_per_event", "Number of TT_{Ref} per event", kTH1F, - {{15, 0.5, 15.5}}); - spectra.add("hTTSig_per_event", "Number of TT_{Sig} per event", kTH1F, - {{10, 0.5, 10.5}}); - - spectra.add("hJetPtEtaPhiRhoArea", "Charact. of inclusive jets", - kTHnSparseF, {pT, pseudorapJets, phiAngle, rho, jetArea}); - - spectra.add("hDPhi_JetPt_Corr_TTRef", - "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_Corr_TTSig", - "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_TTRef", - "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, pT}); - spectra.add("hDPhi_JetPt_TTSig", - "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, pT}); - - spectra.add("hRecoil_JetPt_Corr_TTRef", - "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, - {jetPTcorr}); - spectra.add("hRecoil_JetPt_Corr_TTSig", - "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, - {jetPTcorr}); - spectra.add("hRecoil_JetPt_TTRef", - "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - spectra.add("hRecoil_JetPt_TTSig", - "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - - spectra.add("hJetArea_JetPt_Rho_TTRef", - "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, - {jetArea, pT, rho}); - spectra.add("hJetArea_JetPt_Rho_TTSig", - "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, - {jetArea, pT, rho}); + spectra.add("hEventSelectionCount", "Count # of events in the analysis", kTH1F, {{3, 0.0, 3.}}); + spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(1, "Total # of events"); + spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(2, Form("# of events after sel. %s", evSelToString.data())); + spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(3, "# of events w. outlier"); + + spectra.add("vertexZ", "Z vertex of collisions", kTH1F, {{60, -12., 12.}}); + spectra.add("hHasAssocMcCollision", "Has det. level coll. associat. MC coll.", kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(1, "Yes"); + spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(2, "No"); + + spectra.add("hTrackSelectionCount", "Count # of tracks in the analysis", kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hTrackSelectionCount"))->GetXaxis()->SetBinLabel(1, "Total # of tracks"); + spectra.get(HIST("hTrackSelectionCount"))->GetXaxis()->SetBinLabel(2, Form("# of tracks after sel. %s", trkSelToString.data())); + + spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, {pT, pseudorap, phiAngle}); + spectra.add("hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, {{40, 10., 50.}}); // needed to distinguish merged data from diff. wagons + + spectra.add("hScaledFT0C_vs_Ntrig", "Total number of selected triggers per class vs scaled FT0C", kTH2F, {{multFT0CThresh}, {2, 0.0, 2.}}); + spectra.get(HIST("hScaledFT0C_vs_Ntrig"))->GetYaxis()->SetBinLabel(1, "TT_{ref}"); + spectra.get(HIST("hScaledFT0C_vs_Ntrig"))->GetYaxis()->SetBinLabel(2, "TT_{sig}"); + + spectra.add("hScaledFT0M_vs_Ntrig", "Total number of selected triggers per class vs scaled FT0M", kTH2F, {{multFT0MThresh}, {2, 0.0, 2.}}); + spectra.get(HIST("hScaledFT0M_vs_Ntrig"))->GetYaxis()->SetBinLabel(1, "TT_{ref}"); + spectra.get(HIST("hScaledFT0M_vs_Ntrig"))->GetYaxis()->SetBinLabel(2, "TT_{sig}"); + + spectra.add("hScaledFT0C_vs_TTRef_per_event", "Number of TT_{Ref} per event vs scaled FT0C", kTH2F, {{multFT0CThresh}, {15, 0.5, 15.5}}); + spectra.add("hScaledFT0M_vs_TTRef_per_event", "Number of TT_{Ref} per event vs scaled FT0M", kTH2F, {{multFT0MThresh}, {15, 0.5, 15.5}}); + + spectra.add("hScaledFT0C_vs_TTSig_per_event", "Number of TT_{Sig} per event vs scaled FT0C", kTH2F, {{multFT0CThresh}, {10, 0.5, 10.5}}); + spectra.add("hScaledFT0M_vs_TTSig_per_event", "Number of TT_{Sig} per event vs scaled FT0M", kTH2F, {{multFT0MThresh}, {10, 0.5, 10.5}}); + + spectra.add("hJetPtEtaPhiRhoArea", "Charact. of inclusive jets", kTHnSparseF, {pT, pseudorapJets, phiAngle, rho, jetArea}); + + spectra.add("hScaledFT0C_DPhi_JetPt_Corr_TTRef", "Events w. TT_{Ref}: scaled FT0C & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0CThresh, deltaPhiAngle, jetPTcorr}); + spectra.add("hScaledFT0M_DPhi_JetPt_Corr_TTRef", "Events w. TT_{Ref}: scaled FT0M & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0MThresh, deltaPhiAngle, jetPTcorr}); + + spectra.add("hScaledFT0C_DPhi_JetPt_Corr_TTSig", "Events w. TT_{Sig}: scaled FT0C & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0CThresh, deltaPhiAngle, jetPTcorr}); + spectra.add("hScaledFT0M_DPhi_JetPt_Corr_TTSig", "Events w. TT_{Sig}: scaled FT0M & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0MThresh, deltaPhiAngle, jetPTcorr}); + + spectra.add("hScaledFT0C_DPhi_JetPt_TTRef", "Events w. TT_{Ref}: scaled FT0C & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0CThresh, deltaPhiAngle, pT}); + spectra.add("hScaledFT0M_DPhi_JetPt_TTRef", "Events w. TT_{Ref}: scaled FT0M & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0MThresh, deltaPhiAngle, pT}); + + spectra.add("hScaledFT0C_DPhi_JetPt_TTSig", "Events w. TT_{Sig}: scaled FT0C & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0CThresh, deltaPhiAngle, pT}); + spectra.add("hScaledFT0M_DPhi_JetPt_TTSig", "Events w. TT_{Sig}: scaled FT0M & #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH3F, {multFT0MThresh, deltaPhiAngle, pT}); + + spectra.add("hScaledFT0C_Recoil_JetPt_Corr_TTRef", "Events w. TT_{Ref}: scaled FT0C & #it{p}_{T} of recoil jets", kTH2F, {multFT0CThresh, jetPTcorr}); + spectra.add("hScaledFT0M_Recoil_JetPt_Corr_TTRef", "Events w. TT_{Ref}: scaled FT0M & #it{p}_{T} of recoil jets", kTH2F, {multFT0MThresh, jetPTcorr}); + + spectra.add("hScaledFT0C_Recoil_JetPt_Corr_TTSig", "Events w. TT_{Sig}: scaled FT0C & #it{p}_{T} of recoil jets", kTH2F, {multFT0CThresh, jetPTcorr}); + spectra.add("hScaledFT0M_Recoil_JetPt_Corr_TTSig", "Events w. TT_{Sig}: scaled FT0M & #it{p}_{T} of recoil jets", kTH2F, {multFT0MThresh, jetPTcorr}); + + spectra.add("hScaledFT0C_Recoil_JetPt_TTRef", "Events w. TT_{Ref}: scaled FT0C & #it{p}_{T} of recoil jets", kTH2F, {multFT0CThresh, pT}); + spectra.add("hScaledFT0M_Recoil_JetPt_TTRef", "Events w. TT_{Ref}: scaled FT0M & #it{p}_{T} of recoil jets", kTH2F, {multFT0MThresh, pT}); + + spectra.add("hScaledFT0C_Recoil_JetPt_TTSig", "Events w. TT_{Sig}: scaled FT0C & #it{p}_{T} of recoil jets", kTH2F, {multFT0CThresh, pT}); + spectra.add("hScaledFT0M_Recoil_JetPt_TTSig", "Events w. TT_{Sig}: scaled FT0M & #it{p}_{T} of recoil jets", kTH2F, {multFT0MThresh, pT}); + + spectra.add("hJetArea_JetPt_Rho_TTRef", "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); + spectra.add("hJetArea_JetPt_Rho_TTSig", "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); + + spectra.add("hScaledFT0C_Rho_TTRef", "Events w. TT_{Ref}: scaled FT0C & #rho", kTH2F, {multFT0CThresh, rho}); + spectra.add("hScaledFT0M_Rho_TTRef", "Events w. TT_{Ref}: scaled FT0M & #rho", kTH2F, {multFT0MThresh, rho}); + + spectra.add("hScaledFT0C_Rho_TTSig", "Events w. TT_{Sig}: scaled FT0C & #rho", kTH2F, {multFT0CThresh, rho}); + spectra.add("hScaledFT0M_Rho_TTSig", "Events w. TT_{Sig}: scaled FT0M & #rho", kTH2F, {multFT0MThresh, rho}); + + spectra.add("hScaledFT0C_TTRef", "Events w. TT_{Ref}: scaled FT0C", kTH1F, {scaledFT0C}); + spectra.add("hScaledFT0M_TTRef", "Events w. TT_{Ref}: scaled FT0M", kTH1F, {scaledFT0M}); + + spectra.add("hScaledFT0C_TTSig", "Events w. TT_{Sig}: scaled FT0C", kTH1F, {scaledFT0C}); + spectra.add("hScaledFT0M_TTSig", "Events w. TT_{Sig}: scaled FT0M", kTH1F, {scaledFT0M}); } // List of MC particle level distributions if (doprocessMCPartLevel || doprocessMCPartLevelWeighted) { - spectra.add("vertexZMC", "Z vertex of jmccollision", kTH1F, - {{60, -12., 12.}}); + spectra.add("vertexZMC", "Z vertex of jmccollision", kTH1F, {{60, -12., 12.}}); spectra.add("ptHat", "Distribution of pT hat", kTH1F, {{500, 0.0, 100.}}); - spectra.add("hEventSelectionCountPartLevel", - "Count # of events in the part. level analysis", kTH1F, - {{2, 0.0, 2.}}); - spectra.get(HIST("hEventSelectionCountPartLevel")) - ->GetXaxis() - ->SetBinLabel(1, "Total # of events"); - spectra.get(HIST("hEventSelectionCountPartLevel")) - ->GetXaxis() - ->SetBinLabel(2, "# of events w. outlier"); - - spectra.add("hCountNumberOutliersFrameWork", - "Count # of outlier events based on flag from JE fw", kTH1F, - {{1, 0.0, 1.}}); - spectra.get(HIST("hCountNumberOutliersFrameWork")) - ->GetXaxis() - ->SetBinLabel(1, "Oulier flag true"); - - spectra.add("hPartPtEtaPhi", "Charact. of particles", kTH3F, - {pT, pseudorap, phiAngle}); - spectra.add("hNtrig_Part", "Total number of selected triggers per class", - kTH1F, {{2, 0.0, 2.}}); - spectra.get(HIST("hNtrig_Part")) - ->GetXaxis() - ->SetBinLabel(1, "TT_{ref}"); - spectra.get(HIST("hNtrig_Part")) - ->GetXaxis() - ->SetBinLabel(2, "TT_{sig}"); - - spectra.add("hTTRef_per_event_Part", "Number of TT_{Ref} per event", - kTH1F, {{15, 0.5, 15.5}}); - spectra.add("hTTSig_per_event_Part", "Number of TT_{Sig} per event", - kTH1F, {{10, 0.5, 10.5}}); - - spectra.add("hJetPtEtaPhiRhoArea_Part", - "Charact. of inclusive part. level jets", kTHnSparseF, - {pT, pseudorapJets, phiAngle, rho, jetArea}); - - spectra.add("hDPhi_JetPt_Corr_TTRef_Part", - "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_Corr_TTSig_Part", - "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_TTRef_Part", - "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, pT}); - spectra.add("hDPhi_JetPt_TTSig_Part", - "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", - kTH2F, {deltaPhiAngle, pT}); - - spectra.add("hRecoil_JetPt_Corr_TTRef_Part", - "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, - {jetPTcorr}); - spectra.add("hRecoil_JetPt_Corr_TTSig_Part", - "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, - {jetPTcorr}); - spectra.add("hRecoil_JetPt_TTRef_Part", - "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - spectra.add("hRecoil_JetPt_TTSig_Part", - "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - - spectra.add("hJetArea_JetPt_Rho_TTRef_Part", - "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, - {jetArea, pT, rho}); - spectra.add("hJetArea_JetPt_Rho_TTSig_Part", - "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, - {jetArea, pT, rho}); - - spectra.add("hDiffInOutlierRemove", - "Difference between pT hat from code and fw", kTH1F, - {{502, -0.2, 50.}}); + spectra.add("hEventSelectionCountPartLevel", "Count # of events in the part. level analysis", kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hEventSelectionCountPartLevel"))->GetXaxis()->SetBinLabel(1, "Total # of events"); + spectra.get(HIST("hEventSelectionCountPartLevel"))->GetXaxis()->SetBinLabel(2, "# of events w. outlier"); + + spectra.add("hCountNumberOutliersFrameWork", "Count # of outlier events based on flag from JE fw", kTH1F, {{1, 0.0, 1.}}); + spectra.get(HIST("hCountNumberOutliersFrameWork"))->GetXaxis()->SetBinLabel(1, "Outlier flag true"); + + spectra.add("hPartPtEtaPhi", "Charact. of particles", kTH3F, {pT, pseudorap, phiAngle}); + spectra.add("hNtrig_Part", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hNtrig_Part"))->GetXaxis()->SetBinLabel(1, "TT_{ref}"); + spectra.get(HIST("hNtrig_Part"))->GetXaxis()->SetBinLabel(2, "TT_{sig}"); + + spectra.add("hTTRef_per_event_Part", "Number of TT_{Ref} per event", kTH1F, {{15, 0.5, 15.5}}); + spectra.add("hTTSig_per_event_Part", "Number of TT_{Sig} per event", kTH1F, {{10, 0.5, 10.5}}); + + spectra.add("hJetPtEtaPhiRhoArea_Part", "Charact. of inclusive part. level jets", kTHnSparseF, {pT, pseudorapJets, phiAngle, rho, jetArea}); + + spectra.add("hDPhi_JetPt_Corr_TTRef_Part", "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, jetPTcorr}); + spectra.add("hDPhi_JetPt_Corr_TTSig_Part", "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, jetPTcorr}); + spectra.add("hDPhi_JetPt_TTRef_Part", "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, pT}); + spectra.add("hDPhi_JetPt_TTSig_Part", "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, pT}); + + spectra.add("hRecoil_JetPt_Corr_TTRef_Part", "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {jetPTcorr}); + spectra.add("hRecoil_JetPt_Corr_TTSig_Part", "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {jetPTcorr}); + spectra.add("hRecoil_JetPt_TTRef_Part", "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); + spectra.add("hRecoil_JetPt_TTSig_Part", "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); + + spectra.add("hJetArea_JetPt_Rho_TTRef_Part", "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); + spectra.add("hJetArea_JetPt_Rho_TTSig_Part", "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); + + spectra.add("hDiffInOutlierRemove", "Difference between pT hat from code and fw", kTH1F, {{502, -0.2, 50.}}); } // Jet matching: part. vs. det. if (doprocessJetsMatched || doprocessJetsMatchedWeighted) { - spectra.add("hJetPt_DetLevel_vs_PartLevel", - "Correlation jet pT at det. vs. part. levels", kTH2F, - {{200, 0.0, 200.}, {200, 0.0, 200.}}); + spectra.add("hJetPt_DetLevel_vs_PartLevel", "Correlation jet pT at det. vs. part. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel", "Correlation jet pT at // part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); - spectra.add("hJetPt_DetLevel_vs_PartLevel_RecoilJets", - "Correlation recoil jet pT at part. vs. det. levels", kTH2F, - {{200, 0.0, 200.}, {200, 0.0, 200.}}); - // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel_RecoilJets", - // "Correlation recoil jet pT at part. vs. det. levels", kTH2F, - // {jetPTcorr, jetPTcorr}); - - spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, - {{200, 0.0, 200.}}); - // spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", - // kTH1F, {jetPTcorr}); - spectra.add("hMissedJets_pT_RecoilJets", - "Part. level jets w/o matched pair", kTH1F, - {{200, 0.0, 200.}}); - // spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o - // matched pair", kTH1F, {jetPTcorr}); - spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, - {{200, 0.0, 200.}}); - // spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", - // kTH1F, {jetPTcorr}); - spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", - kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o - // matched pair", kTH1F, {jetPTcorr}); - - spectra.add( - "hJetPt_resolution", - "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", - kTH2F, {{100, -5., 5.}, pT}); - spectra.add( - "hJetPt_resolution_RecoilJets", - "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", - kTH2F, {{100, -5., 5.}, pT}); - - spectra.add("hJetPhi_resolution", - "#varphi resolution as a func. of jet #it{p}_{T, part}", - kTH2F, {{40, -1., 1.}, pT}); - spectra.add("hJetPhi_resolution_RecoilJets", - "#varphi resolution as a func. of jet #it{p}_{T, part}", - kTH2F, {{40, -1., 1.}, pT}); - - spectra.add("hNumberMatchedJetsPerOneBaseJet", - "# of taged jets per 1 base jet vs. jet pT", kTH2F, - {{10, 0.5, 10.5}, {100, 0.0, 100.}}); + spectra.add("hJetPt_DetLevel_vs_PartLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); + // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); + + spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); + spectra.add("hMissedJets_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); + + spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); + spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); + + spectra.add("hJetPt_resolution", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT}); + spectra.add("hJetPt_resolution_RecoilJets", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT}); + + spectra.add("hJetPhi_resolution", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT}); + spectra.add("hJetPhi_resolution_RecoilJets", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT}); + + spectra.add("hNumberMatchedJetsPerOneBaseJet", "# of tagged jets per 1 base jet vs. jet pT", kTH2F, {{10, 0.5, 10.5}, {100, 0.0, 100.}}); } if (doprocessMultiplicity) { - spectra.add("hMultFT0A", "Mult. signal from FTOA", kTH1F, - {{1500, 0.0, 30000.}}); - spectra.add("hMultFT0C", "Mult. signal from FTOC", kTH1F, - {{1500, 0.0, 30000.}}); - spectra.add("hMultFT0M", "Total mult. signal from FT0A & FTOC", kTH1F, - {{3000, 0.0, 60000.}}); - - spectra.add("hScaleMultFT0A", "Scaled mult. signal from FTOA", kTH1F, - {{200, 0.0, 20.}}); - spectra.add("hScaleMultFT0C", "Scaled mult. signal from FTOC", kTH1F, - {{200, 0.0, 20.}}); - spectra.add("hScaleMultFT0M", "Scaled total mult. signal from FT0A & FTOC", kTH1F, - {{2000, 0.0, 20.}}); - spectra.add("hScaleMultFT0M_v2", "Scaled total mult. signal from FT0A & FTOC", kTH1F, - {{2000, 0.0, 20.}}); - - spectra.add("hMultZNA", "Mult. signal from ZDC A-side", kTH1F, - {{500, 0.0, 10000.}}); - spectra.add("hMultZNC", "Mult. signal from ZDC C-side", kTH1F, - {{500, 0.0, 10000.}}); - spectra.add("hMultZNM", "Total mult. signal from ZDCs", kTH1F, - {{1000, 0.0, 20000.}}); + spectra.add("hMultFT0A", "Mult. signal from FTOA", kTH1F, {{2000, 0.0, 40000.}}); + spectra.add("hMultFT0C", "Mult. signal from FTOC", kTH1F, {{2000, 0.0, 40000.}}); + spectra.add("hMultFT0M", "Total mult. signal from FT0A & FTOC", kTH1F, {{3000, 0.0, 60000.}}); + + spectra.add("hScaleMultFT0A", "Scaled mult. signal from FTOA", kTH1F, {{200, 0.0, 20., "FT0A / #LT FT0A #GT"}}); + spectra.add("hScaleMultFT0C", "Scaled mult. signal from FTOC", kTH1F, {scaledFT0C}); + spectra.add("hScaleMultFT0M", "Scaled total mult. signal from FT0A & FTOC", kTH1F, {scaledFT0M}); + + spectra.add("hMultZNA", "Mult. signal from ZDC A-side", kTH1F, {{1000, 0.0, 5000.}}); + spectra.add("hMultZNC", "Mult. signal from ZDC C-side", kTH1F, {{1000, 0.0, 5000.}}); + spectra.add("hMultZNM", "Total mult. signal from ZDCs", kTH1F, {{4000, 0.0, 8000.}}); // Correlations - spectra.add("hMultFT0A_vs_ZNA", "Correlation of signals FTOA vs ZNA", - kTH2F, {{1500, 0.0, 30000.}, {500, 0.0, 10000.}}); - spectra.add("hMultFT0C_vs_ZNC", "Correlation of signals FTOC vs ZNC", - kTH2F, {{1500, 0.0, 30000.}, {500, 0.0, 10000.}}); - spectra.add("hMultFT0M_vs_ZNM", "Correlation of signals FTOM vs ZNM", - kTH2F, {{3000, 0.0, 60000.}, {1000, 0.0, 20000.}}); - spectra.add("hScaleMultFT0A_vs_ZNA", "Correlation of signals FT0A/meanFT0A vs ZNA", - kTH2F, {{200, 0.0, 20.}, {500, 0.0, 10000.}}); - spectra.add("hScaleMultFT0C_vs_ZNC", "Correlation of signals FT0C/meanFT0C vs ZNC", - kTH2F, {{200, 0.0, 20.}, {500, 0.0, 10000.}}); - spectra.add("hScaleMultFT0M_vs_ZNM", "Correlation of signals FT0M/meanTF0M vs ZNM", - kTH2F, {{200, 0.0, 20.}, {1000, 0.0, 20000.}}); - spectra.add("hScaleMultFT0Mv2_vs_ZNM", "Correlation of signals FT0M/meanTF0M v2 vs ZNM", - kTH2F, {{200, 0.0, 20.}, {1000, 0.0, 20000.}}); + spectra.add("hMultFT0A_vs_ZNA", "Correlation of signals FTOA vs ZNA", kTH2F, {{2000, 0.0, 40000.}, {1000, 0.0, 5000.}}); + spectra.add("hMultFT0C_vs_ZNC", "Correlation of signals FTOC vs ZNC", kTH2F, {{2000, 0.0, 40000.}, {1000, 0.0, 5000.}}); + spectra.add("hMultFT0M_vs_ZNM", "Correlation of signals FTOM vs ZNM", kTH2F, {{3000, 0.0, 60000.}, {4000, 0.0, 8000.}}); + + spectra.add("hScaleMultFT0A_vs_ZNA", "Correlation of signals FT0A/meanFT0A vs ZNA", kTH2F, {{200, 0.0, 20., "FT0A / #LT FT0A #GT"}, {1000, 0.0, 5000.}}); + spectra.add("hScaleMultFT0C_vs_ZNC", "Correlation of signals FT0C/meanFT0C vs ZNC", kTH2F, {{scaledFT0C}, {1000, 0.0, 5000.}}); + spectra.add("hScaleMultFT0M_vs_ZNM", "Correlation of signals FT0M^{*} vs ZNM", kTH2F, {{scaledFT0M}, {4000, 0.0, 8000.}}); + spectra.add("hScaleMultFT0M_vs_ZNA_vs_ZNC", "Correlation of signals FT0M^{*} vs ZNA vs ZNC", kTH3F, {{scaledFT0M}, {1000, 0.0, 5000.}, {1000, 0.0, 5000.}}); } } @@ -458,6 +337,11 @@ struct RecoilJets { double phiTT = 0.; int nTT = 0; float pTHat = getPtHat(weight); + float rho = collision.rho(); + float multFT0A = collision.multFT0A(); + float multFT0C = collision.multFT0C(); + float scaledFT0C = getScaledFT0C(multFT0C); + float scaledFT0M = getScaledFT0M(multFT0A, multFT0C); auto dice = rand->Rndm(); if (dice < fracSig) @@ -477,18 +361,19 @@ struct RecoilJets { if (skipTrack(track)) continue; + float trackPt = track.pt(); + spectra.fill(HIST("hTrackSelectionCount"), 1.5); - spectra.fill(HIST("hTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), - weight); + spectra.fill(HIST("hTrackPtEtaPhi"), trackPt, track.eta(), track.phi(), weight); // Search for TT candidate - if (bSigEv && (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax)) { + if (bSigEv && (trackPt > ptTTsigMin && trackPt < ptTTsigMax)) { vPhiOfTT.push_back(track.phi()); - spectra.fill(HIST("hTTSig_pT"), track.pt(), weight); + spectra.fill(HIST("hTTSig_pT"), trackPt, weight); ++nTT; } - if (!bSigEv && (track.pt() > ptTTrefMin && track.pt() < ptTTrefMax)) { + if (!bSigEv && (trackPt > ptTTrefMin && trackPt < ptTTrefMax)) { vPhiOfTT.push_back(track.phi()); ++nTT; } @@ -499,11 +384,21 @@ struct RecoilJets { phiTT = getPhiTT(vPhiOfTT); if (bSigEv) { - spectra.fill(HIST("hNtrig"), 1.5, weight); - spectra.fill(HIST("hTTSig_per_event"), nTT, weight); + spectra.fill(HIST("hScaledFT0C_vs_Ntrig"), scaledFT0C, 1.5, weight); + spectra.fill(HIST("hScaledFT0M_vs_Ntrig"), scaledFT0M, 1.5, weight); + spectra.fill(HIST("hScaledFT0C_vs_TTSig_per_event"), scaledFT0C, nTT, weight); + spectra.fill(HIST("hScaledFT0M_vs_TTSig_per_event"), scaledFT0M, nTT, weight); + + spectra.fill(HIST("hScaledFT0C_TTSig"), scaledFT0C, weight); + spectra.fill(HIST("hScaledFT0M_TTSig"), scaledFT0M, weight); } else { - spectra.fill(HIST("hNtrig"), 0.5, weight); - spectra.fill(HIST("hTTRef_per_event"), nTT, weight); + spectra.fill(HIST("hScaledFT0C_vs_Ntrig"), scaledFT0C, 0.5, weight); + spectra.fill(HIST("hScaledFT0M_vs_Ntrig"), scaledFT0M, 0.5, weight); + spectra.fill(HIST("hScaledFT0C_vs_TTRef_per_event"), scaledFT0C, nTT, weight); + spectra.fill(HIST("hScaledFT0M_vs_TTRef_per_event"), scaledFT0M, nTT, weight); + + spectra.fill(HIST("hScaledFT0C_TTRef"), scaledFT0C, weight); + spectra.fill(HIST("hScaledFT0M_TTRef"), scaledFT0M, weight); } } @@ -512,37 +407,51 @@ struct RecoilJets { if (isJetWithHighPtConstituent(jet, tracks)) continue; - spectra.fill(HIST("hJetPtEtaPhiRhoArea"), jet.pt(), jet.eta(), jet.phi(), - collision.rho(), jet.area(), weight); + float jetPt = jet.pt(); + float jetArea = jet.area(); + float jetPtCorr = jetPt - rho * jetArea; + + spectra.fill(HIST("hJetPtEtaPhiRhoArea"), jetPt, jet.eta(), jet.phi(), rho, jetArea, weight); if (nTT > 0) { auto [dphi, bRecoilJet] = isRecoilJet(jet, phiTT); if (bSigEv) { + spectra.fill(HIST("hScaledFT0C_Rho_TTSig"), scaledFT0C, rho, weight); + spectra.fill(HIST("hScaledFT0M_Rho_TTSig"), scaledFT0M, rho, weight); + + spectra.fill(HIST("hScaledFT0C_DPhi_JetPt_Corr_TTSig"), scaledFT0C, dphi, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_DPhi_JetPt_Corr_TTSig"), scaledFT0M, dphi, jetPtCorr, weight); - spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig"), dphi, - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hDPhi_JetPt_TTSig"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig"), jet.area(), jet.pt(), - collision.rho(), weight); + spectra.fill(HIST("hScaledFT0C_DPhi_JetPt_TTSig"), scaledFT0C, dphi, jetPt, weight); + spectra.fill(HIST("hScaledFT0M_DPhi_JetPt_TTSig"), scaledFT0M, dphi, jetPt, weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig"), jetArea, jetPt, rho, weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig"), - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hRecoil_JetPt_TTSig"), jet.pt(), weight); + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_Corr_TTSig"), scaledFT0C, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_Corr_TTSig"), scaledFT0M, jetPtCorr, weight); + + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_TTSig"), scaledFT0C, jetPt, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_TTSig"), scaledFT0M, jetPt, weight); } } else { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef"), dphi, - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hDPhi_JetPt_TTRef"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef"), jet.area(), jet.pt(), - collision.rho(), weight); + spectra.fill(HIST("hScaledFT0C_Rho_TTRef"), scaledFT0C, rho, weight); + spectra.fill(HIST("hScaledFT0M_Rho_TTRef"), scaledFT0M, rho, weight); + + spectra.fill(HIST("hScaledFT0C_DPhi_JetPt_Corr_TTRef"), scaledFT0C, dphi, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_DPhi_JetPt_Corr_TTRef"), scaledFT0M, dphi, jetPtCorr, weight); + + spectra.fill(HIST("hScaledFT0C_DPhi_JetPt_TTRef"), scaledFT0C, dphi, jetPt, weight); + spectra.fill(HIST("hScaledFT0M_DPhi_JetPt_TTRef"), scaledFT0M, dphi, jetPt, weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef"), jetArea, jetPt, rho, weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef"), - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hRecoil_JetPt_TTRef"), jet.pt(), weight); + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_Corr_TTRef"), scaledFT0C, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_Corr_TTRef"), scaledFT0M, jetPtCorr, weight); + + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_TTRef"), scaledFT0C, jetPt, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_TTRef"), scaledFT0M, jetPt, weight); } } } @@ -558,6 +467,8 @@ struct RecoilJets { double phiTT = 0.; int nTT = 0; float pTHat = getPtHat(weight); + float rho = collision.rho(); + spectra.fill(HIST("ptHat"), pTHat, weight); auto dice = rand->Rndm(); @@ -576,22 +487,23 @@ struct RecoilJets { if (!pdgParticle) continue; + float particlePt = particle.pt(); + // Need charge and physical primary particles bool bParticleNeutral = (static_cast(pdgParticle->Charge()) == 0); if (bParticleNeutral || !particle.isPhysicalPrimary()) continue; - spectra.fill(HIST("hPartPtEtaPhi"), particle.pt(), particle.eta(), - particle.phi(), weight); + spectra.fill(HIST("hPartPtEtaPhi"), particlePt, particle.eta(), particle.phi(), weight); if (bSigEv && - (particle.pt() > ptTTsigMin && particle.pt() < ptTTsigMax)) { + (particlePt > ptTTsigMin && particlePt < ptTTsigMax)) { vPhiOfTT.push_back(particle.phi()); ++nTT; } if (!bSigEv && - (particle.pt() > ptTTrefMin && particle.pt() < ptTTrefMax)) { + (particlePt > ptTTrefMin && particlePt < ptTTrefMax)) { vPhiOfTT.push_back(particle.phi()); ++nTT; } @@ -611,8 +523,11 @@ struct RecoilJets { } for (const auto& jet : jets) { - spectra.fill(HIST("hJetPtEtaPhiRhoArea_Part"), jet.pt(), jet.eta(), - jet.phi(), collision.rho(), jet.area(), weight); + float jetPt = jet.pt(); + float jetArea = jet.area(); + float jetPtCorr = jetPt - rho * jetArea; + + spectra.fill(HIST("hJetPtEtaPhiRhoArea_Part"), jetPt, jet.eta(), jet.phi(), rho, jetArea, weight); if (nTT > 0) { @@ -620,30 +535,24 @@ struct RecoilJets { if (bSigEv) { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig_Part"), dphi, - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hDPhi_JetPt_TTSig_Part"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig_Part"), jet.area(), - jet.pt(), collision.rho(), weight); + spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig_Part"), dphi, jetPtCorr, weight); + spectra.fill(HIST("hDPhi_JetPt_TTSig_Part"), dphi, jetPt, weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig_Part"), jetArea, jetPt, rho, weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig_Part"), - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hRecoil_JetPt_TTSig_Part"), jet.pt(), weight); + spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig_Part"), jetPtCorr, weight); + spectra.fill(HIST("hRecoil_JetPt_TTSig_Part"), jetPt, weight); } } else { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef_Part"), dphi, - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hDPhi_JetPt_TTRef_Part"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef_Part"), jet.area(), - jet.pt(), collision.rho(), weight); + spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef_Part"), dphi, jetPtCorr, weight); + spectra.fill(HIST("hDPhi_JetPt_TTRef_Part"), dphi, jetPt, weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef_Part"), jetArea, jetPt, rho, weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef_Part"), - jet.pt() - collision.rho() * jet.area(), weight); - spectra.fill(HIST("hRecoil_JetPt_TTRef_Part"), jet.pt(), weight); + spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef_Part"), jetPtCorr, weight); + spectra.fill(HIST("hRecoil_JetPt_TTRef_Part"), jetPt, weight); } } } @@ -689,39 +598,39 @@ struct RecoilJets { void fillMultiplicityHistograms(Collision const& collision, float weight = 1.) { - - spectra.fill(HIST("hMultFT0A"), collision.multFT0A(), weight); - spectra.fill(HIST("hMultFT0C"), collision.multFT0C(), weight); - spectra.fill(HIST("hMultFT0M"), collision.multFT0M(), weight); - - float scaledFT0Mv2 = 0.5 * (collision.multFT0A() / meanFT0A + collision.multFT0C() / meanFT0C); - - spectra.fill(HIST("hScaleMultFT0A"), collision.multFT0A() / meanFT0A, weight); - spectra.fill(HIST("hScaleMultFT0C"), collision.multFT0C() / meanFT0C, weight); - spectra.fill(HIST("hScaleMultFT0M"), collision.multFT0M() / meanFT0M, weight); - spectra.fill(HIST("hScaleMultFT0M_v2"), scaledFT0Mv2, - weight); - - spectra.fill(HIST("hMultZNA"), collision.multZNA(), weight); - spectra.fill(HIST("hMultZNC"), collision.multZNC(), weight); - spectra.fill(HIST("hMultZNM"), collision.multZNA() + collision.multZNC(), - weight); + float multFT0A = collision.multFT0A(); + float multFT0C = collision.multFT0C(); + float multFT0M = collision.multFT0M(); + float scaledFT0A = getScaledFT0A(multFT0A); + float scaledFT0C = getScaledFT0C(multFT0C); + float scaledFT0M = getScaledFT0M(multFT0A, multFT0C); + + float multZNA = collision.multZNA(); + float multZNC = collision.multZNC(); + float multZNM = collision.multZNA() + collision.multZNC(); + + // Individual distributions + spectra.fill(HIST("hMultFT0A"), multFT0A, weight); + spectra.fill(HIST("hMultFT0C"), multFT0C, weight); + spectra.fill(HIST("hMultFT0M"), multFT0M, weight); + + spectra.fill(HIST("hScaleMultFT0A"), scaledFT0A, weight); + spectra.fill(HIST("hScaleMultFT0C"), scaledFT0C, weight); + spectra.fill(HIST("hScaleMultFT0M"), scaledFT0M, weight); + + spectra.fill(HIST("hMultZNA"), multZNA, weight); + spectra.fill(HIST("hMultZNC"), multZNC, weight); + spectra.fill(HIST("hMultZNM"), multZNM, weight); // Correlations - spectra.fill(HIST("hMultFT0A_vs_ZNA"), collision.multFT0A(), - collision.multZNA(), weight); - spectra.fill(HIST("hMultFT0C_vs_ZNC"), collision.multFT0C(), - collision.multZNC(), weight); - spectra.fill(HIST("hMultFT0M_vs_ZNM"), collision.multFT0M(), - collision.multZNA() + collision.multZNC(), weight); - spectra.fill(HIST("hScaleMultFT0A_vs_ZNA"), collision.multFT0A() / meanFT0A, - collision.multZNA(), weight); - spectra.fill(HIST("hScaleMultFT0C_vs_ZNC"), collision.multFT0C() / meanFT0C, - collision.multZNC(), weight); - spectra.fill(HIST("hScaleMultFT0M_vs_ZNM"), collision.multFT0M() / meanFT0M, - collision.multZNA() + collision.multZNC(), weight); - spectra.fill(HIST("hScaleMultFT0Mv2_vs_ZNM"), scaledFT0Mv2, - collision.multZNA() + collision.multZNC(), weight); + spectra.fill(HIST("hMultFT0A_vs_ZNA"), multFT0A, multZNA, weight); + spectra.fill(HIST("hMultFT0C_vs_ZNC"), multFT0C, multZNC, weight); + spectra.fill(HIST("hMultFT0M_vs_ZNM"), multFT0M, multZNM, weight); + + spectra.fill(HIST("hScaleMultFT0A_vs_ZNA"), scaledFT0A, multZNA, weight); + spectra.fill(HIST("hScaleMultFT0C_vs_ZNC"), scaledFT0C, multZNC, weight); + spectra.fill(HIST("hScaleMultFT0M_vs_ZNM"), scaledFT0M, multZNM, weight); + spectra.fill(HIST("hScaleMultFT0M_vs_ZNA_vs_ZNC"), scaledFT0M, multZNA, multZNC, weight); } //------------------------------------------------------------------------------ @@ -862,8 +771,7 @@ struct RecoilJets { fillMultiplicityHistograms(collision); } - PROCESS_SWITCH(RecoilJets, processMultiplicity, "process multiplicity", - false); + PROCESS_SWITCH(RecoilJets, processMultiplicity, "process multiplicity", false); //------------------------------------------------------------------------------ // Auxiliary functions @@ -871,17 +779,13 @@ struct RecoilJets { bool skipEvent(const Collision& coll) { /// \brief: trigger cut is needed for pp data - return !jetderiveddatautilities::selectCollision(coll, - eventSelectionBits) || - !jetderiveddatautilities::selectTrigger(coll, triggerMaskBits); + return !jetderiveddatautilities::selectCollision(coll, eventSelectionBits) || !jetderiveddatautilities::selectTrigger(coll, triggerMaskBits); } template bool skipMBGapEvent(const Collision& coll) { - return skipMBGapEvents && - coll.subGeneratorId() == - jetderiveddatautilities::JCollisionSubGeneratorId::mbGap; + return skipMBGapEvents && coll.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap; } template @@ -893,8 +797,7 @@ struct RecoilJets { template std::tuple isRecoilJet(const Jet& jet, double phiTT) { - double dphi = std::fabs( - RecoDecay::constrainAngle(jet.phi() - phiTT, -constants::math::PI)); + double dphi = std::fabs(RecoDecay::constrainAngle(jet.phi() - phiTT, -constants::math::PI)); return {dphi, (constants::math::PI - recoilRegion) < dphi}; } @@ -909,6 +812,21 @@ struct RecoilJets { return 10. / (std::pow(weight, 1.0 / pTHatExponent)); } + float getScaledFT0A(const float multFT0A) + { + return multFT0A / meanFT0A; + } + + float getScaledFT0C(const float multFT0C) + { + return multFT0C / meanFT0C; + } + + float getScaledFT0M(const float multFT0A, const float multFT0C) + { + return 0.5 * (getScaledFT0A(multFT0A) + getScaledFT0C(multFT0C)); + } + template bool isJetWithHighPtConstituent(Jet const& jet, Tracks const&) { @@ -927,11 +845,11 @@ struct RecoilJets { bool bIsBaseJetRecoil, TracksTable const& tracks, float weight = 1.) { + float partJetPt = partJet.pt(); bool bIsThereMatchedJet = partJet.has_matchedJetGeo(); if (bIsThereMatchedJet) { - const auto& jetsMatched = - partJet.template matchedJetGeo_as>(); + const auto& jetsMatched = partJet.template matchedJetGeo_as>(); for (const auto& jetMatched : jetsMatched) { @@ -940,36 +858,29 @@ struct RecoilJets { if (skipMatchedDetJet) { // Miss jets - spectra.fill(HIST("hMissedJets_pT"), partJet.pt(), weight); + spectra.fill(HIST("hMissedJets_pT"), partJetPt, weight); if (bIsBaseJetRecoil) - spectra.fill(HIST("hMissedJets_pT_RecoilJets"), partJet.pt(), weight); + spectra.fill(HIST("hMissedJets_pT_RecoilJets"), partJetPt, weight); } else { - spectra.fill(HIST("hNumberMatchedJetsPerOneBaseJet"), - jetsMatched.size(), jetMatched.pt(), weight); - spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetMatched.pt(), - partJet.pt(), weight); - spectra.fill(HIST("hJetPt_resolution"), - (partJet.pt() - jetMatched.pt()) / partJet.pt(), - partJet.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution"), - partJet.phi() - jetMatched.phi(), partJet.pt(), weight); + float detJetPt = jetMatched.pt(); + + spectra.fill(HIST("hNumberMatchedJetsPerOneBaseJet"), jetsMatched.size(), detJetPt, weight); + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), detJetPt, partJetPt, weight); + spectra.fill(HIST("hJetPt_resolution"), (partJetPt - detJetPt) / partJetPt, partJetPt, weight); + spectra.fill(HIST("hJetPhi_resolution"), partJet.phi() - jetMatched.phi(), partJetPt, weight); if (bIsBaseJetRecoil) { - spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), - jetMatched.pt(), partJet.pt(), weight); - spectra.fill(HIST("hJetPt_resolution_RecoilJets"), - (partJet.pt() - jetMatched.pt()) / partJet.pt(), - partJet.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), - partJet.phi() - jetMatched.phi(), partJet.pt(), weight); + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), detJetPt, partJetPt, weight); + spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (partJetPt - detJetPt) / partJetPt, partJetPt, weight); + spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), partJet.phi() - jetMatched.phi(), partJetPt, weight); } } } } else { // Miss jets - spectra.fill(HIST("hMissedJets_pT"), partJet.pt(), weight); + spectra.fill(HIST("hMissedJets_pT"), partJetPt, weight); if (bIsBaseJetRecoil) - spectra.fill(HIST("hMissedJets_pT_RecoilJets"), partJet.pt(), weight); + spectra.fill(HIST("hMissedJets_pT_RecoilJets"), partJetPt, weight); } // Fake jets diff --git a/PWGJE/Tasks/v0QA.cxx b/PWGJE/Tasks/v0QA.cxx index 8b79b780ae4..c66bf164def 100644 --- a/PWGJE/Tasks/v0QA.cxx +++ b/PWGJE/Tasks/v0QA.cxx @@ -254,6 +254,11 @@ struct V0QA { } if (doprocessTestWeightedJetFinder) { registry.add("tests/weighted/hEvents", "Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); + registry.add("tests/weighted/V0PtEtaPhi", "V0 Pt Eta Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/weighted/K0SPtEtaPhi", "K0S Pt Eta Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/weighted/LambdaPtEtaPhi", "Lambda Pt Eta Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/weighted/AntiLambdaPtEtaPhi", "AntiLambda Pt Eta Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/weighted/JetPtEtaPhi", "Jet Pt, Eta, Phi", HistType::kTH3D, {axisJetPt, axisEta, axisPhi}); registry.add("tests/weighted/JetPtEtaV0Pt", "Jet Pt, Eta, V0 Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); registry.add("tests/weighted/JetPtEtaV0Z", "Jet Pt, Eta, V0 Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}); @@ -266,6 +271,15 @@ struct V0QA { } if (doprocessTestSubtractedJetFinder) { registry.add("tests/hEvents", "Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); + registry.add("tests/nosub/V0PtEtaPhi", "V0 Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/nosub/K0SPtEtaPhi", "K0S Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/nosub/LambdaPtEtaPhi", "Lambda Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/nosub/AntiLambdaPtEtaPhi", "AntiLambda Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/sub/V0PtEtaPhi", "V0 Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/sub/K0SPtEtaPhi", "K0S Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/sub/LambdaPtEtaPhi", "Lambda Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/sub/AntiLambdaPtEtaPhi", "AntiLambda Pt, Eta, Phi", HistType::kTH3D, {axisV0Pt, axisEta, axisPhi}); + registry.add("tests/nosub/JetPtEtaPhi", "Jet Pt, Eta, Phi", HistType::kTH3D, {axisJetPt, axisEta, axisPhi}); registry.add("tests/nosub/JetPtEtaV0Pt", "Jet Pt, Eta, V0 Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); registry.add("tests/nosub/JetPtEtaV0Z", "Jet Pt, Eta, V0 Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}); @@ -287,6 +301,7 @@ struct V0QA { registry.add("tests/sub/JetPtEtaAntiLambdaZ", "Jet Pt, Eta, AntiLambda Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}); } if (doprocessV0TrackQA) { + registry.add("tracks/hEvents", "evts", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); registry.add("tracks/Pos", "pos", HistType::kTHnSparseD, {axisV0Pt, axisV0Pt, axisEta, axisPhi}); registry.add("tracks/Neg", "neg", HistType::kTHnSparseD, {axisV0Pt, axisV0Pt, axisEta, axisPhi}); registry.add("tracks/Pt", "pt", HistType::kTHnSparseD, {axisV0Pt, axisV0Pt, axisV0Pt, axisPtDiff, axisPtRelDiff}); @@ -481,6 +496,24 @@ struct V0QA { auto daughters = particle.daughtersIds(); return ((negId == daughters[0] && posId == daughters[1]) || (posId == daughters[0] && negId == daughters[1])); } + template + bool genV0PassesEfficiencyCuts(T const& pv0) + { + if (!pv0.has_daughters() || !pv0.isPhysicalPrimary()) + return false; + if (std::abs(pv0.y()) > yPartMax) + return false; + + return true; + } + template + bool recV0PassesEfficiencyCuts(T const& v0) + { + if (!v0.has_mcParticle() || v0.isRejectedCandidate()) + return false; + + return true; + } template bool hasITSHit(T const& track, int layer) @@ -489,25 +522,34 @@ struct V0QA { return (track.itsClusterMap() & (1 << ibit)); } - template - void fillMcDV0(T const& v0, bool correctCollision, double weight) + bool isV0RandomlyRejected() { - int pdg = v0.mcParticle().pdgCode(); + return (gRandom->Uniform() > v0Fraction); + } + + template + void fillMcDV0(T const& v0, U const& pv0, bool correctCollision, double weight) + { + int pdg = pv0.pdgCode(); + double pt = pv0.pt(); + double eta = v0.eta(); + double radius = v0.v0radius(); + if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("inclusive/K0SPtEtaMass"), v0.pt(), v0.eta(), v0.mK0Short(), weight); - registry.fill(HIST("inclusive/InvMassK0STrue"), v0.pt(), v0.v0radius(), v0.mK0Short(), weight); + registry.fill(HIST("inclusive/K0SPtEtaMass"), pt, eta, v0.mK0Short(), weight); + registry.fill(HIST("inclusive/InvMassK0STrue"), pt, radius, v0.mK0Short(), weight); if (!correctCollision) - registry.fill(HIST("inclusive/K0SPtEtaMassWrongCollision"), v0.pt(), v0.eta(), v0.mK0Short(), weight); + registry.fill(HIST("inclusive/K0SPtEtaMassWrongCollision"), pt, eta, v0.mK0Short(), weight); } else if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("inclusive/LambdaPtEtaMass"), v0.pt(), v0.eta(), v0.mLambda(), weight); - registry.fill(HIST("inclusive/InvMassLambdaTrue"), v0.pt(), v0.v0radius(), v0.mLambda(), weight); + registry.fill(HIST("inclusive/LambdaPtEtaMass"), pt, eta, v0.mLambda(), weight); + registry.fill(HIST("inclusive/InvMassLambdaTrue"), pt, radius, v0.mLambda(), weight); if (!correctCollision) - registry.fill(HIST("inclusive/LambdaPtEtaMassWrongCollision"), v0.pt(), v0.eta(), v0.mLambda(), weight); + registry.fill(HIST("inclusive/LambdaPtEtaMassWrongCollision"), pt, eta, v0.mLambda(), weight); } else if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("inclusive/AntiLambdaPtEtaMass"), v0.pt(), v0.eta(), v0.mAntiLambda(), weight); - registry.fill(HIST("inclusive/InvMassAntiLambdaTrue"), v0.pt(), v0.v0radius(), v0.mAntiLambda(), weight); + registry.fill(HIST("inclusive/AntiLambdaPtEtaMass"), pt, eta, v0.mAntiLambda(), weight); + registry.fill(HIST("inclusive/InvMassAntiLambdaTrue"), pt, radius, v0.mAntiLambda(), weight); if (!correctCollision) - registry.fill(HIST("inclusive/AntiLambdaPtEtaMassWrongCollision"), v0.pt(), v0.eta(), v0.mAntiLambda(), weight); + registry.fill(HIST("inclusive/AntiLambdaPtEtaMassWrongCollision"), pt, eta, v0.mAntiLambda(), weight); } } @@ -519,60 +561,69 @@ struct V0QA { registry.fill(HIST("jets/JetsPtEta"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), weight); } } - template - void fillMcDV0InJets(T const& mcdjet, U const& v0, bool correctCollision, double weight) + template + void fillMcDV0InJets(T const& mcdjet, U const& v0, V const& pv0, bool correctCollision, double weight) { int pdg = v0.mcParticle().pdgCode(); - double z = v0.pt() / mcdjet.pt(); + double pt = pv0.pt(); + double ptjet = mcdjet.pt(); + double eta = mcdjet.eta(); + double z = pt / ptjet; + if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("jets/JetPtEtaK0SPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetPtEtaK0SZ"), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetPtEtaK0SPt"), ptjet, eta, pt, weight); + registry.fill(HIST("jets/JetPtEtaK0SZ"), ptjet, eta, z, weight); if (!correctCollision) { - registry.fill(HIST("jets/JetPtEtaK0SPtWrongCollision"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetPtEtaK0SZWrongCollision"), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetPtEtaK0SPtWrongCollision"), ptjet, eta, pt, weight); + registry.fill(HIST("jets/JetPtEtaK0SZWrongCollision"), ptjet, eta, z, weight); } } else if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("jets/JetPtEtaLambdaPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetPtEtaLambdaZ"), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetPtEtaLambdaPt"), ptjet, eta, pt, weight); + registry.fill(HIST("jets/JetPtEtaLambdaZ"), ptjet, eta, z, weight); if (!correctCollision) { - registry.fill(HIST("jets/JetPtEtaLambdaPtWrongCollision"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetPtEtaLambdaZWrongCollision"), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetPtEtaLambdaPtWrongCollision"), ptjet, eta, pt, weight); + registry.fill(HIST("jets/JetPtEtaLambdaZWrongCollision"), ptjet, eta, z, weight); } } else if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("jets/JetPtEtaAntiLambdaPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetPtEtaAntiLambdaZ"), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetPtEtaAntiLambdaPt"), ptjet, eta, pt, weight); + registry.fill(HIST("jets/JetPtEtaAntiLambdaZ"), ptjet, eta, z, weight); if (!correctCollision) { - registry.fill(HIST("jets/JetPtEtaAntiLambdaPtWrongCollision"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetPtEtaAntiLambdaZWrongCollision"), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetPtEtaAntiLambdaPtWrongCollision"), ptjet, eta, pt, weight); + registry.fill(HIST("jets/JetPtEtaAntiLambdaZWrongCollision"), ptjet, eta, z, weight); } } } - template - void fillMcDV0InMatchedJets(T const& mcpjet, U const& mcdjet, V const& v0, bool correctCollision, double weight) + template + void fillMcDV0InMatchedJets(T const& mcpjet, U const& mcdjet, V const& v0, W const& pv0, bool correctCollision, double weight) { int pdg = v0.mcParticle().pdgCode(); - double z = v0.pt() / mcdjet.pt(); + double ptjetmcp = mcpjet.pt(); + double ptjetmcd = mcdjet.pt(); + double eta = mcdjet.eta(); + double pt = pv0.pt(); + double z = pt / ptjetmcp; + if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("jets/JetsPtEtaK0SPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetsPtEtaK0SZ"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetsPtEtaK0SPt"), ptjetmcp, ptjetmcd, eta, pt, weight); + registry.fill(HIST("jets/JetsPtEtaK0SZ"), ptjetmcp, ptjetmcd, eta, z, weight); if (!correctCollision) { - registry.fill(HIST("jets/JetsPtEtaK0SPtWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetsPtEtaK0SZWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetsPtEtaK0SPtWrongCollision"), ptjetmcp, ptjetmcd, eta, pt, weight); + registry.fill(HIST("jets/JetsPtEtaK0SZWrongCollision"), ptjetmcp, ptjetmcd, eta, z, weight); } } else if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("jets/JetsPtEtaLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetsPtEtaLambdaZ"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetsPtEtaLambdaPt"), ptjetmcp, ptjetmcd, eta, pt, weight); + registry.fill(HIST("jets/JetsPtEtaLambdaZ"), ptjetmcp, ptjetmcd, eta, z, weight); if (!correctCollision) { - registry.fill(HIST("jets/JetsPtEtaLambdaPtWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetsPtEtaLambdaZWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetsPtEtaLambdaPtWrongCollision"), ptjetmcp, ptjetmcd, eta, pt, weight); + registry.fill(HIST("jets/JetsPtEtaLambdaZWrongCollision"), ptjetmcp, ptjetmcd, eta, z, weight); } } else if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("jets/JetsPtEtaAntiLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetsPtEtaAntiLambdaZ"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetsPtEtaAntiLambdaPt"), ptjetmcp, ptjetmcd, eta, pt, weight); + registry.fill(HIST("jets/JetsPtEtaAntiLambdaZ"), ptjetmcp, ptjetmcd, eta, z, weight); if (!correctCollision) { - registry.fill(HIST("jets/JetsPtEtaAntiLambdaPtWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/JetsPtEtaAntiLambdaZWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + registry.fill(HIST("jets/JetsPtEtaAntiLambdaPtWrongCollision"), ptjetmcp, ptjetmcd, eta, pt, weight); + registry.fill(HIST("jets/JetsPtEtaAntiLambdaZWrongCollision"), ptjetmcp, ptjetmcd, eta, z, weight); } } } @@ -618,6 +669,121 @@ struct V0QA { } } + template + void fillWeightedJetFinderInclusiveV0(T const& v0) + { + registry.fill(HIST("tests/weighted/V0PtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (v0.isK0SCandidate()) + registry.fill(HIST("tests/weighted/K0SPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (v0.isLambdaCandidate()) + registry.fill(HIST("tests/weighted/LambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (v0.isAntiLambdaCandidate()) + registry.fill(HIST("tests/weighted/AntiLambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + } + + template + void fillWeightedJetFinderJet(T const& jet) + { + registry.fill(HIST("tests/weighted/JetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); + } + + template + void fillWeightedJetFinderV0InJet(T const& jet, U const& v0) + { + double z = v0.pt() / jet.pt(); + registry.fill(HIST("tests/weighted/JetPtEtaV0Pt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/weighted/JetPtEtaV0Z"), jet.pt(), jet.eta(), z); + + if (v0.isK0SCandidate()) { + registry.fill(HIST("tests/weighted/JetPtEtaK0SPt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/weighted/JetPtEtaK0SZ"), jet.pt(), jet.eta(), z); + } + if (v0.isLambdaCandidate()) { + registry.fill(HIST("tests/weighted/JetPtEtaLambdaPt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/weighted/JetPtEtaLambdaZ"), jet.pt(), jet.eta(), z); + } + if (v0.isAntiLambdaCandidate()) { + registry.fill(HIST("tests/weighted/JetPtEtaAntiLambdaPt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/weighted/JetPtEtaAntiLambdaZ"), jet.pt(), jet.eta(), z); + } + } + + template + void fillSubtractedJetFinderInclusiveV0(T const& v0) + { + bool randomlyRejected = isV0RandomlyRejected(); + + registry.fill(HIST("tests/nosub/V0PtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (!randomlyRejected) + registry.fill(HIST("tests/sub/V0PtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + + if (v0.isK0SCandidate()) { + registry.fill(HIST("tests/nosub/K0SPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (!randomlyRejected) + registry.fill(HIST("tests/sub/K0SPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + } + if (v0.isLambdaCandidate()) { + registry.fill(HIST("tests/nosub/LambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (!randomlyRejected) + registry.fill(HIST("tests/sub/LambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + } + if (v0.isAntiLambdaCandidate()) { + registry.fill(HIST("tests/nosub/AntiLambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + if (!randomlyRejected) + registry.fill(HIST("tests/sub/AntiLambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + } + } + + template + void fillSubtractedJetFinderJetNoSubtraction(T const& jet) + { + registry.fill(HIST("tests/nosub/JetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); + } + + template + void fillSubtractedJetFinderV0InJetNoSubtraction(T const& jet, U const& v0) + { + double z = v0.pt() / jet.pt(); + registry.fill(HIST("tests/nosub/JetPtEtaV0Pt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/nosub/JetPtEtaV0Z"), jet.pt(), jet.eta(), z); + if (v0.isK0SCandidate()) { + registry.fill(HIST("tests/nosub/JetPtEtaK0SPt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/nosub/JetPtEtaK0SZ"), jet.pt(), jet.eta(), z); + } + if (v0.isLambdaCandidate()) { + registry.fill(HIST("tests/nosub/JetPtEtaLambdaPt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/nosub/JetPtEtaLambdaZ"), jet.pt(), jet.eta(), z); + } + if (v0.isAntiLambdaCandidate()) { + registry.fill(HIST("tests/nosub/JetPtEtaAntiLambdaPt"), jet.pt(), jet.eta(), v0.pt()); + registry.fill(HIST("tests/nosub/JetPtEtaAntiLambdaZ"), jet.pt(), jet.eta(), z); + } + } + + template + void fillSubtractedJetFinderJetSubtracted(T const& jet, double ptjetsub) + { + registry.fill(HIST("tests/sub/JetPtEtaPhi"), ptjetsub, jet.eta(), jet.phi()); + } + + void fillSubtractedJetFinderV0InJetSubtracted(const double ptjetsub, const double etajet, const double v0Pt, const int v0Type) + { + double z = v0Pt / ptjetsub; + registry.fill(HIST("tests/sub/JetPtEtaV0Pt"), ptjetsub, etajet, v0Pt); + registry.fill(HIST("tests/sub/JetPtEtaV0Z"), ptjetsub, etajet, z); + + if (v0Type == PDG_t::kK0Short) { + registry.fill(HIST("tests/sub/JetPtEtaK0SPt"), ptjetsub, etajet, v0Pt); + registry.fill(HIST("tests/sub/JetPtEtaK0SZ"), ptjetsub, etajet, z); + } else if (v0Type == PDG_t::kLambda0) { + registry.fill(HIST("tests/sub/JetPtEtaLambdaPt"), ptjetsub, etajet, v0Pt); + registry.fill(HIST("tests/sub/JetPtEtaLambdaZ"), ptjetsub, etajet, z); + } else if (v0Type == PDG_t::kLambda0Bar) { + registry.fill(HIST("tests/sub/JetPtEtaAntiLambdaPt"), ptjetsub, etajet, v0Pt); + registry.fill(HIST("tests/sub/JetPtEtaAntiLambdaZ"), ptjetsub, etajet, z); + } + } + template void fillTrackQa(V const& v0) { @@ -887,28 +1053,39 @@ struct V0QA { registry.fill(HIST("inclusive/hEvents"), 2.5, weight); for (const auto& v0 : v0s) { - if (!v0.has_mcParticle() || v0.isRejectedCandidate()) + if (!recV0PassesEfficiencyCuts(v0)) + continue; + + auto pv0 = v0.mcParticle(); + if (!genV0PassesEfficiencyCuts(pv0)) continue; bool correctCollision = (mcColl.mcCollisionId() == v0.mcParticle().mcCollisionId()); - fillMcDV0(v0, correctCollision, weight); + fillMcDV0(v0, pv0, correctCollision, weight); } // v0 loop for (const auto& mcdjet : mcdjets) { fillMcDJets(mcdjet, weight); + for (const auto& v0 : mcdjet.template candidates_as()) { - if (!v0.has_mcParticle() || v0.isRejectedCandidate()) + if (!recV0PassesEfficiencyCuts(v0)) + continue; + + auto pv0 = v0.mcParticle(); + if (!genV0PassesEfficiencyCuts(pv0)) continue; bool correctCollision = (mcColl.mcCollisionId() == v0.mcParticle().mcCollisionId()); - fillMcDV0InJets(mcdjet, v0, correctCollision, weight); + fillMcDV0InJets(mcdjet, v0, pv0, correctCollision, weight); for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - for (const auto& pv0 : mcpjet.template candidates_as()) { - if (!v0sAreMatched(v0, pv0, jTracks)) + for (const auto& pv0injet : mcpjet.template candidates_as()) { + if (!genV0PassesEfficiencyCuts(pv0injet)) + continue; + if (!v0sAreMatched(v0, pv0injet, jTracks)) continue; - fillMcDV0InMatchedJets(mcpjet, mcdjet, v0, correctCollision, weight); + fillMcDV0InMatchedJets(mcpjet, mcdjet, v0, pv0, correctCollision, weight); } // v0 particle loop } // mcpjet loop } // v0 loop @@ -939,9 +1116,7 @@ struct V0QA { registry.fill(HIST("inclusive/hMcEvents"), 2.5, weight); for (const auto& pv0 : pv0s) { - if (!pv0.has_daughters() || !pv0.isPhysicalPrimary()) - continue; - if (std::abs(pv0.y()) > yPartMax) + if (!genV0PassesEfficiencyCuts(pv0)) continue; fillMcPV0(pv0, weight); @@ -954,7 +1129,7 @@ struct V0QA { fillMcPJets(jet, weight); for (const auto& pv0 : jet.template candidates_as()) { - if (!pv0.has_daughters() || !pv0.isPhysicalPrimary()) + if (!genV0PassesEfficiencyCuts(pv0)) continue; fillMcPV0InJets(jet, pv0, weight); @@ -1302,7 +1477,7 @@ struct V0QA { PROCESS_SWITCH(V0QA, processFeeddownMatchedJets, "Jets feeddown", false); // Test the difference between excluding V0s from jet finding and subtracting V0s from jets afterwards - void processTestWeightedJetFinder(soa::Filtered::iterator const& jcoll, soa::Join const& jets, aod::CandidatesV0Data const&) + void processTestWeightedJetFinder(soa::Filtered::iterator const& jcoll, soa::Join const& jets, aod::CandidatesV0Data const& v0s) { registry.fill(HIST("tests/weighted/hEvents"), 0.5); if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) @@ -1310,36 +1485,27 @@ struct V0QA { registry.fill(HIST("tests/weighted/hEvents"), 1.5); + for (const auto& v0 : v0s) { + if (v0.isRejectedCandidate()) + continue; + + fillWeightedJetFinderInclusiveV0(v0); + } + for (const auto& jet : jets) { - registry.fill(HIST("tests/weighted/JetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); + fillWeightedJetFinderJet(jet); for (const auto& v0 : jet.template candidates_as()) { if (v0.isRejectedCandidate()) continue; - double z = v0.pt() / jet.pt(); - - registry.fill(HIST("tests/weighted/JetPtEtaV0Pt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/weighted/JetPtEtaV0Z"), jet.pt(), jet.eta(), z); - - if (v0.isK0SCandidate()) { - registry.fill(HIST("tests/weighted/JetPtEtaK0SPt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/weighted/JetPtEtaK0SZ"), jet.pt(), jet.eta(), z); - } - if (v0.isLambdaCandidate()) { - registry.fill(HIST("tests/weighted/JetPtEtaLambdaPt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/weighted/JetPtEtaLambdaZ"), jet.pt(), jet.eta(), z); - } - if (v0.isAntiLambdaCandidate()) { - registry.fill(HIST("tests/weighted/JetPtEtaAntiLambdaPt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/weighted/JetPtEtaAntiLambdaZ"), jet.pt(), jet.eta(), z); - } + fillWeightedJetFinderV0InJet(jet, v0); } } } PROCESS_SWITCH(V0QA, processTestWeightedJetFinder, "Test weighted jet finder", false); - void processTestSubtractedJetFinder(soa::Filtered::iterator const& jcoll, soa::Join const& jets, aod::CandidatesV0Data const&) + void processTestSubtractedJetFinder(soa::Filtered::iterator const& jcoll, soa::Join const& jets, aod::CandidatesV0Data const& v0s) { registry.fill(HIST("tests/hEvents"), 0.5); if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) @@ -1347,33 +1513,24 @@ struct V0QA { registry.fill(HIST("tests/hEvents"), 1.5); + for (const auto& v0 : v0s) { + if (v0.isRejectedCandidate()) + continue; + + fillSubtractedJetFinderInclusiveV0(v0); + } + for (const auto& jet : jets) { - registry.fill(HIST("tests/nosub/JetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); + fillSubtractedJetFinderJetNoSubtraction(jet); std::vector v0Pt; std::vector v0Type; double ptjetsub = jet.pt(); for (const auto& v0 : jet.template candidates_as()) { - double z = v0.pt() / jet.pt(); - - registry.fill(HIST("tests/nosub/JetPtEtaV0Pt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/nosub/JetPtEtaV0Z"), jet.pt(), jet.eta(), z); + fillSubtractedJetFinderV0InJetNoSubtraction(jet, v0); - if (v0.isK0SCandidate()) { - registry.fill(HIST("tests/nosub/JetPtEtaK0SPt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/nosub/JetPtEtaK0SZ"), jet.pt(), jet.eta(), z); - } - if (v0.isLambdaCandidate()) { - registry.fill(HIST("tests/nosub/JetPtEtaLambdaPt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/nosub/JetPtEtaLambdaZ"), jet.pt(), jet.eta(), z); - } - if (v0.isAntiLambdaCandidate()) { - registry.fill(HIST("tests/nosub/JetPtEtaAntiLambdaPt"), jet.pt(), jet.eta(), v0.pt()); - registry.fill(HIST("tests/nosub/JetPtEtaAntiLambdaZ"), jet.pt(), jet.eta(), z); - } - - if (gRandom->Uniform() > v0Fraction) { // Rejected V0 + if (isV0RandomlyRejected()) { ptjetsub -= v0.pt(); } else { // Accepted V0 v0Pt.push_back(v0.pt()); @@ -1387,25 +1544,9 @@ struct V0QA { } } // V0s in jet loop - registry.fill(HIST("tests/sub/JetPtEtaPhi"), ptjetsub, jet.eta(), jet.phi()); + fillSubtractedJetFinderJetSubtracted(jet, ptjetsub); for (unsigned int i = 0; i < v0Pt.size(); ++i) { - int type = v0Type[i]; - double pt = v0Pt[i]; - double z = pt / ptjetsub; - - registry.fill(HIST("tests/sub/JetPtEtaV0Pt"), ptjetsub, jet.eta(), pt); - registry.fill(HIST("tests/sub/JetPtEtaV0Z"), ptjetsub, jet.eta(), z); - - if (type == PDG_t::kK0Short) { - registry.fill(HIST("tests/sub/JetPtEtaK0SPt"), ptjetsub, jet.eta(), pt); - registry.fill(HIST("tests/sub/JetPtEtaK0SZ"), ptjetsub, jet.eta(), z); - } else if (type == PDG_t::kLambda0) { - registry.fill(HIST("tests/sub/JetPtEtaLambdaPt"), ptjetsub, jet.eta(), pt); - registry.fill(HIST("tests/sub/JetPtEtaLambdaZ"), ptjetsub, jet.eta(), z); - } else if (type == PDG_t::kLambda0Bar) { - registry.fill(HIST("tests/sub/JetPtEtaAntiLambdaPt"), ptjetsub, jet.eta(), pt); - registry.fill(HIST("tests/sub/JetPtEtaAntiLambdaZ"), ptjetsub, jet.eta(), z); - } + fillSubtractedJetFinderV0InJetSubtracted(ptjetsub, jet.eta(), v0Pt[i], v0Type[i]); } // Accepted V0s in jet loop } // Jets loop } @@ -1413,11 +1554,14 @@ struct V0QA { using DaughterJTracks = soa::Join; using DaughterTracks = soa::Join; - void processV0TrackQA(aod::JetCollision const& /*jcoll*/, aod::CandidatesV0Data const& v0s, DaughterJTracks const&, DaughterTracks const&) + void processV0TrackQA(aod::JetCollision const& jcoll, aod::CandidatesV0Data const& v0s, DaughterJTracks const&, DaughterTracks const&) { - // if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) { - // return; - // } + registry.fill(HIST("tracks/hEvents"), 0.5); + if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) + return; + + registry.fill(HIST("tracks/hEvents"), 1.5); + for (const auto& v0 : v0s) { if (v0.isRejectedCandidate()) continue; diff --git a/PWGLF/DataModel/LFHyperNucleiKinkTables.h b/PWGLF/DataModel/LFHyperNucleiKinkTables.h index a661e4dec32..f36cc896ed8 100644 --- a/PWGLF/DataModel/LFHyperNucleiKinkTables.h +++ b/PWGLF/DataModel/LFHyperNucleiKinkTables.h @@ -37,12 +37,6 @@ DECLARE_SOA_COLUMN(ZMothIU, zMothIU, float); //! Z of DECLARE_SOA_COLUMN(PxMothSV, pxMothSV, float); //! Px of the mother track at the decay vertex DECLARE_SOA_COLUMN(PyMothSV, pyMothSV, float); //! Py of the mother track at the decay vertex DECLARE_SOA_COLUMN(PzMothSV, pzMothSV, float); //! Pz of the mother track at the decay vertex -DECLARE_SOA_COLUMN(RefitPxMothPV, refitPxMothPV, float); //! Refit Px of the mother track at the primary vertex -DECLARE_SOA_COLUMN(RefitPyMothPV, refitPyMothPV, float); //! Refit Py of the mother track at the primary vertex -DECLARE_SOA_COLUMN(RefitPzMothPV, refitPzMothPV, float); //! Refit Pz of the mother track at the primary vertex -DECLARE_SOA_COLUMN(RefitPxMothSV, refitPxMothSV, float); //! Refit Px of the mother track at the decay vertex -DECLARE_SOA_COLUMN(RefitPyMothSV, refitPyMothSV, float); //! Refit Py of the mother track at the decay vertex -DECLARE_SOA_COLUMN(RefitPzMothSV, refitPzMothSV, float); //! Refit Pz of the mother track at the decay vertex DECLARE_SOA_COLUMN(PxDaugSV, pxDaugSV, float); //! Px of the daughter track at the decay vertex DECLARE_SOA_COLUMN(PyDaugSV, pyDaugSV, float); //! Py of the daughter track at the decay vertex DECLARE_SOA_COLUMN(PzDaugSV, pzDaugSV, float); //! Pz of the daughter track at the decay vertex @@ -53,6 +47,9 @@ DECLARE_SOA_COLUMN(DcaKinkTopo, dcaKinkTopo, float); //! DCA DECLARE_SOA_COLUMN(ItsChi2Moth, itsChi2Moth, float); //! ITS chi2 of the mother track DECLARE_SOA_COLUMN(ItsClusterSizesMoth, itsClusterSizesMoth, uint32_t); //! ITS cluster size of the mother track DECLARE_SOA_COLUMN(ItsClusterSizesDaug, itsClusterSizesDaug, uint32_t); //! ITS cluster size of the daughter track +DECLARE_SOA_COLUMN(TpcMomDaug, tpcMomDaug, float); //! TPC momentum of the daughter track +DECLARE_SOA_COLUMN(TpcSignalDaug, tpcSignalDaug, float); //! TPC signal of the daughter track +DECLARE_SOA_COLUMN(TpcNClsPIDDaug, tpcNClsPIDDaug, int16_t); //! Number of TPC clusters used for PID of the daughter track DECLARE_SOA_COLUMN(NSigmaTPCDaug, nSigmaTPCDaug, float); //! Number of tpc sigmas of the daughter track DECLARE_SOA_COLUMN(NSigmaITSDaug, nSigmaITSDaug, float); //! Number of ITS sigmas of the daughter track DECLARE_SOA_COLUMN(NSigmaTOFDaug, nSigmaTOFDaug, float); //! Number of TOF sigmas of the daughter track @@ -90,11 +87,10 @@ DECLARE_SOA_TABLE(HypKinkCand, "AOD", "HYPKINKCANDS", hyperkink::IsMatter, hyperkink::XMothIU, hyperkink::YMothIU, hyperkink::ZMothIU, hyperkink::PxMothSV, hyperkink::PyMothSV, hyperkink::PzMothSV, - hyperkink::RefitPxMothPV, hyperkink::RefitPyMothPV, hyperkink::RefitPzMothPV, - hyperkink::RefitPxMothSV, hyperkink::RefitPyMothSV, hyperkink::RefitPzMothSV, hyperkink::PxDaugSV, hyperkink::PyDaugSV, hyperkink::PzDaugSV, hyperkink::DcaMothPv, hyperkink::DcaDaugPv, hyperkink::DcaKinkTopo, hyperkink::ItsChi2Moth, hyperkink::ItsClusterSizesMoth, hyperkink::ItsClusterSizesDaug, + hyperkink::TpcMomDaug, hyperkink::TpcSignalDaug, hyperkink::TpcNClsPIDDaug, hyperkink::NSigmaTPCDaug, hyperkink::NSigmaITSDaug, hyperkink::NSigmaTOFDaug, hyperkink::PxMothPV, hyperkink::PyMothPV, hyperkink::PzMothPV, hyperkink::UpdatePxMothPV, hyperkink::UpdatePyMothPV, hyperkink::UpdatePzMothPV); @@ -107,11 +103,10 @@ DECLARE_SOA_TABLE(MCHypKinkCand, "AOD", "MCHYPKINKCANDS", hyperkink::IsMatter, hyperkink::XMothIU, hyperkink::YMothIU, hyperkink::ZMothIU, hyperkink::PxMothSV, hyperkink::PyMothSV, hyperkink::PzMothSV, - hyperkink::RefitPxMothPV, hyperkink::RefitPyMothPV, hyperkink::RefitPzMothPV, - hyperkink::RefitPxMothSV, hyperkink::RefitPyMothSV, hyperkink::RefitPzMothSV, hyperkink::PxDaugSV, hyperkink::PyDaugSV, hyperkink::PzDaugSV, hyperkink::DcaMothPv, hyperkink::DcaDaugPv, hyperkink::DcaKinkTopo, hyperkink::ItsChi2Moth, hyperkink::ItsClusterSizesMoth, hyperkink::ItsClusterSizesDaug, + hyperkink::TpcMomDaug, hyperkink::TpcSignalDaug, hyperkink::TpcNClsPIDDaug, hyperkink::NSigmaTPCDaug, hyperkink::NSigmaITSDaug, hyperkink::NSigmaTOFDaug, hyperkink::IsSignal, hyperkink::IsSignalReco, hyperkink::IsCollReco, hyperkink::IsSurvEvSelection, hyperkink::TrueXSV, hyperkink::TrueYSV, hyperkink::TrueZSV, diff --git a/PWGLF/DataModel/LFSigmaTables.h b/PWGLF/DataModel/LFSigmaTables.h index bd808cef106..fdeab068f44 100644 --- a/PWGLF/DataModel/LFSigmaTables.h +++ b/PWGLF/DataModel/LFSigmaTables.h @@ -9,19 +9,28 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Qvectors.h" + #include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" + +#include "Math/Vector3D.h" +#include "TVector3.h" + +#include +#include #ifndef PWGLF_DATAMODEL_LFSIGMATABLES_H_ #define PWGLF_DATAMODEL_LFSIGMATABLES_H_ +using std::array; + // Creating output TTree for sigma analysis namespace o2::aod { @@ -29,53 +38,173 @@ namespace o2::aod // for real data namespace sigma0Core { -DECLARE_SOA_COLUMN(SigmapT, sigmapT, float); -DECLARE_SOA_COLUMN(SigmaMass, sigmaMass, float); -DECLARE_SOA_COLUMN(SigmaRapidity, sigmaRapidity, float); -DECLARE_SOA_COLUMN(SigmaOPAngle, sigmaOPAngle, float); -DECLARE_SOA_COLUMN(SigmaCentrality, sigmaCentrality, float); -DECLARE_SOA_COLUMN(SigmaRunNumber, sigmaRunNumber, int); -DECLARE_SOA_COLUMN(SigmaTimestamp, sigmaTimestamp, uint64_t); +DECLARE_SOA_COLUMN(X, x, float); +DECLARE_SOA_COLUMN(Y, y, float); +DECLARE_SOA_COLUMN(Z, z, float); +DECLARE_SOA_COLUMN(DCADaughters, dcadaughters, float); + +DECLARE_SOA_COLUMN(PhotonPx, photonPx, float); +DECLARE_SOA_COLUMN(PhotonPy, photonPy, float); +DECLARE_SOA_COLUMN(PhotonPz, photonPz, float); +DECLARE_SOA_COLUMN(PhotonMass, photonMass, float); + +DECLARE_SOA_COLUMN(LambdaPx, lambdaPx, float); +DECLARE_SOA_COLUMN(LambdaPy, lambdaPy, float); +DECLARE_SOA_COLUMN(LambdaPz, lambdaPz, float); +DECLARE_SOA_COLUMN(LambdaMass, lambdaMass, float); +DECLARE_SOA_COLUMN(AntiLambdaMass, antilambdaMass, float); + +//______________________________________________________ +// DYNAMIC COLUMNS +// Sigma0 +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Sigma0 px + [](float photonPx, float lambdaPx) -> float { return photonPx + lambdaPx; }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Sigma0 py + [](float photonPy, float lambdaPy) -> float { return photonPy + lambdaPy; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Sigma0 pz + [](float photonPz, float lambdaPz) -> float { return photonPz + lambdaPz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, + [](float photonPx, float photonPy, float lambdaPx, float lambdaPy) -> float { + return RecoDecay::pt(array{photonPx + lambdaPx, photonPy + lambdaPy}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Total momentum in GeV/c + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonPx + lambdaPx, photonPy + lambdaPy, photonPz + lambdaPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0Mass, sigma0Mass, + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + std::array pVecPhotons{photonPx, photonPy, photonPz}; + std::array pVecLambda{lambdaPx, lambdaPy, lambdaPz}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0Y, sigma0Y, + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::y(std::array{photonPx + lambdaPx, photonPy + lambdaPy, photonPz + lambdaPz}, o2::constants::physics::MassSigma0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Phi in the range [0, 2pi) + [](float photonPx, float photonPy, float lambdaPx, float lambdaPy) -> float { return RecoDecay::phi(photonPx + lambdaPx, photonPy + lambdaPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Pseudorapidity + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::eta(std::array{photonPx + lambdaPx, photonPy + lambdaPy, photonPz + lambdaPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Radius, radius, //! Sigma0 decay radius (2D, centered at zero) + [](float x, float y) -> float { return RecoDecay::sqrtSumOfSquares(x, y); }); + +DECLARE_SOA_DYNAMIC_COLUMN(OPAngle, opAngle, + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) { + TVector3 v1(photonPx, photonPy, photonPz); + TVector3 v2(lambdaPx, lambdaPy, lambdaPz); + return v1.Angle(v2); + }); + +// Photon +DECLARE_SOA_DYNAMIC_COLUMN(PhotonPt, photonPt, //! Transverse momentum in GeV/c + [](float photonPx, float photonPy) -> float { + return RecoDecay::sqrtSumOfSquares(photonPx, photonPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonP, photonp, //! Total momentum in GeV/c + [](float photonPx, float photonPy, float photonPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonPx, photonPy, photonPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonEta, photonEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photonPx, float photonPy, float photonPz) -> float { + return RecoDecay::eta(std::array{photonPx, photonPy, photonPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonY, photonY, //! Rapidity + [](float photonPx, float photonPy, float photonPz) -> float { + return RecoDecay::y(std::array{photonPx, photonPy, photonPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonPhi, photonPhi, //! Phi in the range [0, 2pi) + [](float photonPx, float photonPy) -> float { return RecoDecay::phi(photonPx, photonPy); }); + +// Lambda/ALambda +DECLARE_SOA_DYNAMIC_COLUMN(LambdaPt, lambdaPt, //! Transverse momentum in GeV/c + [](float lambdaPx, float lambdaPy) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaPx, lambdaPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaP, lambdap, //! Total momentum in GeV/c + [](float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaPx, lambdaPy, lambdaPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaEta, lambdaEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::eta(std::array{lambdaPx, lambdaPy, lambdaPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaY, lambdaY, //! Rapidity + [](float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::y(std::array{lambdaPx, lambdaPy, lambdaPz}, o2::constants::physics::MassLambda); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaPhi, lambdaPhi, //! Phi in the range [0, 2pi) + [](float lambdaPx, float lambdaPy) -> float { return RecoDecay::phi(lambdaPx, lambdaPy); }); } // namespace sigma0Core DECLARE_SOA_TABLE(Sigma0Cores, "AOD", "SIGMA0CORES", - sigma0Core::SigmapT, - sigma0Core::SigmaMass, - sigma0Core::SigmaRapidity, - sigma0Core::SigmaOPAngle, - sigma0Core::SigmaCentrality, - sigma0Core::SigmaRunNumber, - sigma0Core::SigmaTimestamp); + // Basic properties + sigma0Core::X, sigma0Core::Y, sigma0Core::Z, sigma0Core::DCADaughters, + sigma0Core::PhotonPx, sigma0Core::PhotonPy, sigma0Core::PhotonPz, sigma0Core::PhotonMass, + sigma0Core::LambdaPx, sigma0Core::LambdaPy, sigma0Core::LambdaPz, sigma0Core::LambdaMass, sigma0Core::AntiLambdaMass, + + // Dynamic columns + sigma0Core::Px, + sigma0Core::Py, + sigma0Core::Pz, + sigma0Core::Pt, + sigma0Core::P, + sigma0Core::Sigma0Mass, + sigma0Core::Sigma0Y, + sigma0Core::Phi, + sigma0Core::Eta, + sigma0Core::Radius, + sigma0Core::OPAngle, + + sigma0Core::PhotonPt, + sigma0Core::PhotonP, + sigma0Core::PhotonEta, + sigma0Core::PhotonY, + sigma0Core::PhotonPhi, + + sigma0Core::LambdaPt, + sigma0Core::LambdaP, + sigma0Core::LambdaEta, + sigma0Core::LambdaY, + sigma0Core::LambdaPhi); // For Photon extra info -namespace sigmaPhotonExtra +namespace sigma0PhotonExtra { -DECLARE_SOA_COLUMN(PhotonPt, photonPt, float); -DECLARE_SOA_COLUMN(PhotonMass, photonMass, float); +//______________________________________________________ +// REGULAR COLUMNS FOR SIGMA0PHOTON DECLARE_SOA_COLUMN(PhotonQt, photonQt, float); DECLARE_SOA_COLUMN(PhotonAlpha, photonAlpha, float); -DECLARE_SOA_COLUMN(PhotonRadius, photonRadius, float); DECLARE_SOA_COLUMN(PhotonCosPA, photonCosPA, float); DECLARE_SOA_COLUMN(PhotonDCADau, photonDCADau, float); DECLARE_SOA_COLUMN(PhotonDCANegPV, photonDCANegPV, float); DECLARE_SOA_COLUMN(PhotonDCAPosPV, photonDCAPosPV, float); +DECLARE_SOA_COLUMN(PhotonRadius, photonRadius, float); DECLARE_SOA_COLUMN(PhotonZconv, photonZconv, float); -DECLARE_SOA_COLUMN(PhotonEta, photonEta, float); -DECLARE_SOA_COLUMN(PhotonY, photonY, float); -DECLARE_SOA_COLUMN(PhotonPhi, photonPhi, float); DECLARE_SOA_COLUMN(PhotonPosTPCNSigmaEl, photonPosTPCNSigmaEl, float); DECLARE_SOA_COLUMN(PhotonNegTPCNSigmaEl, photonNegTPCNSigmaEl, float); -DECLARE_SOA_COLUMN(PhotonPosTPCNSigmaPi, photonPosTPCNSigmaPi, float); -DECLARE_SOA_COLUMN(PhotonNegTPCNSigmaPi, photonNegTPCNSigmaPi, float); DECLARE_SOA_COLUMN(PhotonPosTPCCrossedRows, photonPosTPCCrossedRows, uint8_t); DECLARE_SOA_COLUMN(PhotonNegTPCCrossedRows, photonNegTPCCrossedRows, uint8_t); -DECLARE_SOA_COLUMN(PhotonPosPt, photonPosPt, float); -DECLARE_SOA_COLUMN(PhotonNegPt, photonNegPt, float); DECLARE_SOA_COLUMN(PhotonPosEta, photonPosEta, float); DECLARE_SOA_COLUMN(PhotonNegEta, photonNegEta, float); -DECLARE_SOA_COLUMN(PhotonPosY, photonPosY, float); -DECLARE_SOA_COLUMN(PhotonNegY, photonNegY, float); DECLARE_SOA_COLUMN(PhotonPsiPair, photonPsiPair, float); DECLARE_SOA_COLUMN(PhotonPosITSCls, photonPosITSCls, int); DECLARE_SOA_COLUMN(PhotonNegITSCls, photonNegITSCls, int); @@ -84,52 +213,36 @@ DECLARE_SOA_COLUMN(PhotonNegITSChi2PerNcl, photonNegITSChi2PerNcl, float); DECLARE_SOA_COLUMN(PhotonPosTrackCode, photonPosTrackCode, uint8_t); DECLARE_SOA_COLUMN(PhotonNegTrackCode, photonNegTrackCode, uint8_t); DECLARE_SOA_COLUMN(PhotonV0Type, photonV0Type, uint8_t); -DECLARE_SOA_COLUMN(GammaBDTScore, gammaBDTScore, float); - -} // namespace sigmaPhotonExtra - -DECLARE_SOA_TABLE(SigmaPhotonExtras, "AOD", "SIGMA0PHOTON", - sigmaPhotonExtra::PhotonPt, - sigmaPhotonExtra::PhotonMass, - sigmaPhotonExtra::PhotonQt, - sigmaPhotonExtra::PhotonAlpha, - sigmaPhotonExtra::PhotonRadius, - sigmaPhotonExtra::PhotonCosPA, - sigmaPhotonExtra::PhotonDCADau, - sigmaPhotonExtra::PhotonDCANegPV, - sigmaPhotonExtra::PhotonDCAPosPV, - sigmaPhotonExtra::PhotonZconv, - sigmaPhotonExtra::PhotonEta, - sigmaPhotonExtra::PhotonY, - sigmaPhotonExtra::PhotonPhi, - sigmaPhotonExtra::PhotonPosTPCNSigmaEl, - sigmaPhotonExtra::PhotonNegTPCNSigmaEl, - sigmaPhotonExtra::PhotonPosTPCNSigmaPi, - sigmaPhotonExtra::PhotonNegTPCNSigmaPi, - sigmaPhotonExtra::PhotonPosTPCCrossedRows, - sigmaPhotonExtra::PhotonNegTPCCrossedRows, - sigmaPhotonExtra::PhotonPosPt, - sigmaPhotonExtra::PhotonNegPt, - sigmaPhotonExtra::PhotonPosEta, - sigmaPhotonExtra::PhotonNegEta, - sigmaPhotonExtra::PhotonPosY, - sigmaPhotonExtra::PhotonNegY, - sigmaPhotonExtra::PhotonPsiPair, - sigmaPhotonExtra::PhotonPosITSCls, - sigmaPhotonExtra::PhotonNegITSCls, - sigmaPhotonExtra::PhotonPosITSChi2PerNcl, - sigmaPhotonExtra::PhotonNegITSChi2PerNcl, - sigmaPhotonExtra::PhotonPosTrackCode, - sigmaPhotonExtra::PhotonNegTrackCode, - sigmaPhotonExtra::PhotonV0Type, - sigmaPhotonExtra::GammaBDTScore); + +} // namespace sigma0PhotonExtra + +DECLARE_SOA_TABLE(Sigma0PhotonExtras, "AOD", "SIGMA0PHOTON", + sigma0PhotonExtra::PhotonQt, + sigma0PhotonExtra::PhotonAlpha, + sigma0PhotonExtra::PhotonCosPA, + sigma0PhotonExtra::PhotonDCADau, + sigma0PhotonExtra::PhotonDCANegPV, + sigma0PhotonExtra::PhotonDCAPosPV, + sigma0PhotonExtra::PhotonRadius, + sigma0PhotonExtra::PhotonZconv, + sigma0PhotonExtra::PhotonPosTPCNSigmaEl, + sigma0PhotonExtra::PhotonNegTPCNSigmaEl, + sigma0PhotonExtra::PhotonPosTPCCrossedRows, + sigma0PhotonExtra::PhotonNegTPCCrossedRows, + sigma0PhotonExtra::PhotonPosEta, + sigma0PhotonExtra::PhotonNegEta, + sigma0PhotonExtra::PhotonPsiPair, + sigma0PhotonExtra::PhotonPosITSCls, + sigma0PhotonExtra::PhotonNegITSCls, + sigma0PhotonExtra::PhotonPosITSChi2PerNcl, + sigma0PhotonExtra::PhotonNegITSChi2PerNcl, + sigma0PhotonExtra::PhotonPosTrackCode, + sigma0PhotonExtra::PhotonNegTrackCode, + sigma0PhotonExtra::PhotonV0Type); // For Lambda extra info -namespace sigmaLambdaExtra +namespace sigma0LambdaExtra { -DECLARE_SOA_COLUMN(LambdaPt, lambdaPt, float); -DECLARE_SOA_COLUMN(LambdaMass, lambdaMass, float); -DECLARE_SOA_COLUMN(AntiLambdaMass, antilambdaMass, float); DECLARE_SOA_COLUMN(LambdaQt, lambdaQt, float); DECLARE_SOA_COLUMN(LambdaAlpha, lambdaAlpha, float); DECLARE_SOA_COLUMN(LambdaLifeTime, lambdaLifeTime, float); @@ -138,9 +251,6 @@ DECLARE_SOA_COLUMN(LambdaCosPA, lambdaCosPA, float); DECLARE_SOA_COLUMN(LambdaDCADau, lambdaDCADau, float); DECLARE_SOA_COLUMN(LambdaDCANegPV, lambdaDCANegPV, float); DECLARE_SOA_COLUMN(LambdaDCAPosPV, lambdaDCAPosPV, float); -DECLARE_SOA_COLUMN(LambdaEta, lambdaEta, float); -DECLARE_SOA_COLUMN(LambdaY, lambdaY, float); -DECLARE_SOA_COLUMN(LambdaPhi, lambdaPhi, float); DECLARE_SOA_COLUMN(LambdaPosPrTPCNSigma, lambdaPosPrTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaPosPiTPCNSigma, lambdaPosPiTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaNegPrTPCNSigma, lambdaNegPrTPCNSigma, float); @@ -151,14 +261,8 @@ DECLARE_SOA_COLUMN(ALambdaPrTOFNSigma, aLambdaPrTOFNSigma, float); DECLARE_SOA_COLUMN(ALambdaPiTOFNSigma, aLambdaPiTOFNSigma, float); DECLARE_SOA_COLUMN(LambdaPosTPCCrossedRows, lambdaPosTPCCrossedRows, uint8_t); DECLARE_SOA_COLUMN(LambdaNegTPCCrossedRows, lambdaNegTPCCrossedRows, uint8_t); -DECLARE_SOA_COLUMN(LambdaPosPt, lambdaPosPt, float); -DECLARE_SOA_COLUMN(LambdaNegPt, lambdaNegPt, float); DECLARE_SOA_COLUMN(LambdaPosEta, lambdaPosEta, float); DECLARE_SOA_COLUMN(LambdaNegEta, lambdaNegEta, float); -DECLARE_SOA_COLUMN(LambdaPosPrY, lambdaPosPrY, float); -DECLARE_SOA_COLUMN(LambdaPosPiY, lambdaPosPiY, float); -DECLARE_SOA_COLUMN(LambdaNegPrY, lambdaNegPrY, float); -DECLARE_SOA_COLUMN(LambdaNegPiY, lambdaNegPiY, float); DECLARE_SOA_COLUMN(LambdaPosITSCls, lambdaPosITSCls, int); DECLARE_SOA_COLUMN(LambdaNegITSCls, lambdaNegITSCls, int); DECLARE_SOA_COLUMN(LambdaPosITSChi2PerNcl, lambdaPosChi2PerNcl, float); @@ -166,87 +270,587 @@ DECLARE_SOA_COLUMN(LambdaNegITSChi2PerNcl, lambdaNegChi2PerNcl, float); DECLARE_SOA_COLUMN(LambdaPosTrackCode, lambdaPosTrackCode, uint8_t); DECLARE_SOA_COLUMN(LambdaNegTrackCode, lambdaNegTrackCode, uint8_t); DECLARE_SOA_COLUMN(LambdaV0Type, lambdaV0Type, uint8_t); -DECLARE_SOA_COLUMN(LambdaBDTScore, lambdaBDTScore, float); -DECLARE_SOA_COLUMN(AntiLambdaBDTScore, antilambdaBDTScore, float); - -} // namespace sigmaLambdaExtra - -DECLARE_SOA_TABLE(SigmaLambdaExtras, "AOD", "SIGMA0LAMBDA", - sigmaLambdaExtra::LambdaPt, - sigmaLambdaExtra::LambdaMass, - sigmaLambdaExtra::AntiLambdaMass, - sigmaLambdaExtra::LambdaQt, - sigmaLambdaExtra::LambdaAlpha, - sigmaLambdaExtra::LambdaLifeTime, - sigmaLambdaExtra::LambdaRadius, - sigmaLambdaExtra::LambdaCosPA, - sigmaLambdaExtra::LambdaDCADau, - sigmaLambdaExtra::LambdaDCANegPV, - sigmaLambdaExtra::LambdaDCAPosPV, - sigmaLambdaExtra::LambdaEta, - sigmaLambdaExtra::LambdaY, - sigmaLambdaExtra::LambdaPhi, - sigmaLambdaExtra::LambdaPosPrTPCNSigma, - sigmaLambdaExtra::LambdaPosPiTPCNSigma, - sigmaLambdaExtra::LambdaNegPrTPCNSigma, - sigmaLambdaExtra::LambdaNegPiTPCNSigma, - sigmaLambdaExtra::LambdaPrTOFNSigma, - sigmaLambdaExtra::LambdaPiTOFNSigma, - sigmaLambdaExtra::ALambdaPrTOFNSigma, - sigmaLambdaExtra::ALambdaPiTOFNSigma, - sigmaLambdaExtra::LambdaPosTPCCrossedRows, - sigmaLambdaExtra::LambdaNegTPCCrossedRows, - sigmaLambdaExtra::LambdaPosPt, - sigmaLambdaExtra::LambdaNegPt, - sigmaLambdaExtra::LambdaPosEta, - sigmaLambdaExtra::LambdaNegEta, - sigmaLambdaExtra::LambdaPosPrY, - sigmaLambdaExtra::LambdaPosPiY, - sigmaLambdaExtra::LambdaNegPrY, - sigmaLambdaExtra::LambdaNegPiY, - sigmaLambdaExtra::LambdaPosITSCls, - sigmaLambdaExtra::LambdaNegITSCls, - sigmaLambdaExtra::LambdaPosITSChi2PerNcl, - sigmaLambdaExtra::LambdaNegITSChi2PerNcl, - sigmaLambdaExtra::LambdaPosTrackCode, - sigmaLambdaExtra::LambdaNegTrackCode, - sigmaLambdaExtra::LambdaV0Type, - sigmaLambdaExtra::LambdaBDTScore, - sigmaLambdaExtra::AntiLambdaBDTScore); - -// for MC data -namespace sigmaMCCore + +} // namespace sigma0LambdaExtra + +DECLARE_SOA_TABLE(Sigma0LambdaExtras, "AOD", "SIGMA0LAMBDA", + sigma0LambdaExtra::LambdaQt, + sigma0LambdaExtra::LambdaAlpha, + sigma0LambdaExtra::LambdaLifeTime, + sigma0LambdaExtra::LambdaRadius, + sigma0LambdaExtra::LambdaCosPA, + sigma0LambdaExtra::LambdaDCADau, + sigma0LambdaExtra::LambdaDCANegPV, + sigma0LambdaExtra::LambdaDCAPosPV, + sigma0LambdaExtra::LambdaPosPrTPCNSigma, + sigma0LambdaExtra::LambdaPosPiTPCNSigma, + sigma0LambdaExtra::LambdaNegPrTPCNSigma, + sigma0LambdaExtra::LambdaNegPiTPCNSigma, + sigma0LambdaExtra::LambdaPrTOFNSigma, + sigma0LambdaExtra::LambdaPiTOFNSigma, + sigma0LambdaExtra::ALambdaPrTOFNSigma, + sigma0LambdaExtra::ALambdaPiTOFNSigma, + sigma0LambdaExtra::LambdaPosTPCCrossedRows, + sigma0LambdaExtra::LambdaNegTPCCrossedRows, + sigma0LambdaExtra::LambdaPosEta, + sigma0LambdaExtra::LambdaNegEta, + sigma0LambdaExtra::LambdaPosITSCls, + sigma0LambdaExtra::LambdaNegITSCls, + sigma0LambdaExtra::LambdaPosITSChi2PerNcl, + sigma0LambdaExtra::LambdaNegITSChi2PerNcl, + sigma0LambdaExtra::LambdaPosTrackCode, + sigma0LambdaExtra::LambdaNegTrackCode, + sigma0LambdaExtra::LambdaV0Type); + +// for MC +namespace sigma0MCCore { -DECLARE_SOA_COLUMN(IsSigma, isSigma, bool); // TODO: include PDG + IsPhysicalPrimary -DECLARE_SOA_COLUMN(IsAntiSigma, isAntiSigma, bool); -DECLARE_SOA_COLUMN(SigmaMCPt, sigmaMCPt, float); -DECLARE_SOA_COLUMN(PhotonCandPDGCode, photonCandPDGCode, int); -DECLARE_SOA_COLUMN(PhotonCandPDGCodeMother, photonCandPDGCodeMother, int); -DECLARE_SOA_COLUMN(IsPhotonCandPrimary, isPhotonCandPrimary, bool); -DECLARE_SOA_COLUMN(PhotonMCPt, photonMCPt, float); +DECLARE_SOA_COLUMN(MCradius, mcradius, float); +DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); +DECLARE_SOA_COLUMN(PDGCodeMother, pdgCodeMother, int); +DECLARE_SOA_COLUMN(MCprocess, mcprocess, int); +DECLARE_SOA_COLUMN(IsProducedByGenerator, isProducedByGenerator, bool); + +DECLARE_SOA_COLUMN(PhotonMCPx, photonmcpx, float); +DECLARE_SOA_COLUMN(PhotonMCPy, photonmcpy, float); +DECLARE_SOA_COLUMN(PhotonMCPz, photonmcpz, float); +DECLARE_SOA_COLUMN(IsPhotonPrimary, isPhotonPrimary, bool); +DECLARE_SOA_COLUMN(PhotonPDGCode, photonPDGCode, int); +DECLARE_SOA_COLUMN(PhotonPDGCodeMother, photonPDGCodeMother, int); DECLARE_SOA_COLUMN(PhotonIsCorrectlyAssoc, photonIsCorrectlyAssoc, bool); -DECLARE_SOA_COLUMN(LambdaCandPDGCode, lambdaCandPDGCode, int); -DECLARE_SOA_COLUMN(LambdaCandPDGCodeMother, lambdaCandPDGCodeMother, int); -DECLARE_SOA_COLUMN(IsLambdaCandPrimary, isLambdaCandPrimary, bool); -DECLARE_SOA_COLUMN(LambdaMCPt, lambdaMCPt, float); + +DECLARE_SOA_COLUMN(LambdaMCPx, lambdamcpx, float); +DECLARE_SOA_COLUMN(LambdaMCPy, lambdamcpy, float); +DECLARE_SOA_COLUMN(LambdaMCPz, lambdamcpz, float); +DECLARE_SOA_COLUMN(IsLambdaPrimary, isLambdaPrimary, bool); +DECLARE_SOA_COLUMN(LambdaPDGCode, lambdaPDGCode, int); +DECLARE_SOA_COLUMN(LambdaPDGCodeMother, lambdaPDGCodeMother, int); DECLARE_SOA_COLUMN(LambdaIsCorrectlyAssoc, lambdaIsCorrectlyAssoc, bool); -} // namespace sigmaMCCore - -DECLARE_SOA_TABLE(SigmaMCCores, "AOD", "SIGMA0MCCORES", - sigmaMCCore::IsSigma, - sigmaMCCore::IsAntiSigma, - sigmaMCCore::SigmaMCPt, - sigmaMCCore::PhotonCandPDGCode, - sigmaMCCore::PhotonCandPDGCodeMother, - sigmaMCCore::IsPhotonCandPrimary, - sigmaMCCore::PhotonMCPt, - sigmaMCCore::PhotonIsCorrectlyAssoc, - sigmaMCCore::LambdaCandPDGCode, - sigmaMCCore::LambdaCandPDGCodeMother, - sigmaMCCore::IsLambdaCandPrimary, - sigmaMCCore::LambdaMCPt, - sigmaMCCore::LambdaIsCorrectlyAssoc); +DECLARE_SOA_DYNAMIC_COLUMN(IsSigma0, isSigma0, //! IsSigma0 + [](int pdgCode) -> bool { return pdgCode == 3212; }); + +DECLARE_SOA_DYNAMIC_COLUMN(IsAntiSigma0, isAntiSigma0, //! IsASigma0 + [](int pdgCode) -> bool { return pdgCode == -3212; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPx, mcpx, //! Sigma0 px + [](float photonMCPx, float lambdaMCPx) -> float { return photonMCPx + lambdaMCPx; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPy, mcpy, //! Sigma0 py + [](float photonMCPy, float lambdaMCPy) -> float { return photonMCPy + lambdaMCPy; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPz, mcpz, //! Sigma0 pz + [](float photonMCPz, float lambdaMCPz) -> float { return photonMCPz + lambdaMCPz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPt, mcpt, + [](float photonMCPx, float photonMCPy, float lambdaMCPx, float lambdaMCPy) -> float { + return RecoDecay::pt(array{photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCP, mcp, //! Total momentum in GeV/c + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy, photonMCPz + lambdaMCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0MCMass, sigma0MCMass, + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + std::array pVecPhotons{photonMCPx, photonMCPy, photonMCPz}; + std::array pVecLambda{lambdaMCPx, lambdaMCPy, lambdaMCPz}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0MCY, sigma0MCY, + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::y(std::array{photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy, photonMCPz + lambdaMCPz}, o2::constants::physics::MassSigma0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPhi, mcphi, //! Phi in the range [0, 2pi) + [](float photonMCPx, float photonMCPy, float lambdaMCPx, float lambdaMCPy) -> float { return RecoDecay::phi(photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCEta, mceta, //! Pseudorapidity + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::eta(std::array{photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy, photonMCPz + lambdaMCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCOPAngle, mcopAngle, + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) { + TVector3 v1(photonMCPx, photonMCPy, photonMCPz); + TVector3 v2(lambdaMCPx, lambdaMCPy, lambdaMCPz); + return v1.Angle(v2); + }); + +// Photon +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCPt, photonmcpt, //! Transverse momentum in GeV/c + [](float photonMCPx, float photonMCPy) -> float { + return RecoDecay::sqrtSumOfSquares(photonMCPx, photonMCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCP, photonmcp, //! Total momentum in GeV/c + [](float photonMCPx, float photonMCPy, float photonMCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonMCPx, photonMCPy, photonMCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCEta, photonMCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photonMCPx, float photonMCPy, float photonMCPz) -> float { + return RecoDecay::eta(std::array{photonMCPx, photonMCPy, photonMCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCY, photonMCY, //! Rapidity + [](float photonMCPx, float photonMCPy, float photonMCPz) -> float { + return RecoDecay::y(std::array{photonMCPx, photonMCPy, photonMCPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCPhi, photonMCPhi, //! Phi in the range [0, 2pi) + [](float photonMCPx, float photonMCPy) -> float { return RecoDecay::phi(photonMCPx, photonMCPy); }); + +// Lambda/ALambda +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCPt, lambdamcpt, //! Transverse momentum in GeV/c + [](float lambdaMCPx, float lambdaMCPy) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaMCPx, lambdaMCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCP, lambdamcp, //! Total momentum in GeV/c + [](float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaMCPx, lambdaMCPy, lambdaMCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCEta, lambdaMCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::eta(std::array{lambdaMCPx, lambdaMCPy, lambdaMCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCY, lambdaMCY, //! Rapidity + [](float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::y(std::array{lambdaMCPx, lambdaMCPy, lambdaMCPz}, o2::constants::physics::MassLambda); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCPhi, lambdaMCPhi, //! Phi in the range [0, 2pi) + [](float lambdaMCPx, float lambdaMCPy) -> float { return RecoDecay::phi(lambdaMCPx, lambdaMCPy); }); + +} // namespace sigma0MCCore + +DECLARE_SOA_TABLE(Sigma0MCCores, "AOD", "SIGMA0MCCORES", + // Basic properties + sigma0MCCore::MCradius, sigma0MCCore::PDGCode, sigma0MCCore::PDGCodeMother, sigma0MCCore::MCprocess, sigma0MCCore::IsProducedByGenerator, + + sigma0MCCore::PhotonMCPx, sigma0MCCore::PhotonMCPy, sigma0MCCore::PhotonMCPz, + sigma0MCCore::IsPhotonPrimary, sigma0MCCore::PhotonPDGCode, sigma0MCCore::PhotonPDGCodeMother, sigma0MCCore::PhotonIsCorrectlyAssoc, + + sigma0MCCore::LambdaMCPx, sigma0MCCore::LambdaMCPy, sigma0MCCore::LambdaMCPz, + sigma0MCCore::IsLambdaPrimary, sigma0MCCore::LambdaPDGCode, sigma0MCCore::LambdaPDGCodeMother, sigma0MCCore::LambdaIsCorrectlyAssoc, + + // Dynamic columns + sigma0MCCore::IsSigma0, + sigma0MCCore::IsAntiSigma0, + + sigma0MCCore::MCPx, + sigma0MCCore::MCPy, + sigma0MCCore::MCPz, + sigma0MCCore::MCPt, + sigma0MCCore::MCP, + sigma0MCCore::Sigma0MCMass, + sigma0MCCore::Sigma0MCY, + sigma0MCCore::MCPhi, + sigma0MCCore::MCEta, + sigma0MCCore::MCOPAngle, + + sigma0MCCore::PhotonMCPt, + sigma0MCCore::PhotonMCP, + sigma0MCCore::PhotonMCEta, + sigma0MCCore::PhotonMCY, + sigma0MCCore::PhotonMCPhi, + + sigma0MCCore::LambdaMCPt, + sigma0MCCore::LambdaMCP, + sigma0MCCore::LambdaMCEta, + sigma0MCCore::LambdaMCY, + sigma0MCCore::LambdaMCPhi); + +namespace sigma0Gen +{ +DECLARE_SOA_COLUMN(IsSigma0, isSigma0, bool); // true: sigma0, false: antisigma0 +DECLARE_SOA_COLUMN(ProducedByGenerator, producedByGenerator, bool); +DECLARE_SOA_COLUMN(Sigma0MCPt, sigma0MCPt, float); // MC pT + +} // namespace sigma0Gen + +DECLARE_SOA_TABLE(Sigma0Gens, "AOD", "SIGMA0GENS", + sigma0Gen::IsSigma0, + sigma0Gen::ProducedByGenerator, + sigma0Gen::Sigma0MCPt); + +DECLARE_SOA_TABLE(SigmaCollRef, "AOD", "SIGMACOLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraCollisionId); + +DECLARE_SOA_TABLE(SigmaGenCollRef, "AOD", "SIGMAGENCOLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraMCCollisionId); + +// ___________________________________________________________________________ +// pi0 QA +namespace Pi0Core +{ + +DECLARE_SOA_COLUMN(X, x, float); +DECLARE_SOA_COLUMN(Y, y, float); +DECLARE_SOA_COLUMN(Z, z, float); +DECLARE_SOA_COLUMN(DCADaughters, dcadaughters, float); +DECLARE_SOA_COLUMN(CosPA, cospa, float); + +DECLARE_SOA_COLUMN(Photon1Px, photon1Px, float); +DECLARE_SOA_COLUMN(Photon1Py, photon1Py, float); +DECLARE_SOA_COLUMN(Photon1Pz, photon1Pz, float); +DECLARE_SOA_COLUMN(Photon1Mass, photon1Mass, float); +DECLARE_SOA_COLUMN(Photon1Qt, photon1Qt, float); +DECLARE_SOA_COLUMN(Photon1Alpha, photon1Alpha, float); +DECLARE_SOA_COLUMN(Photon1DCAPosPV, photon1DCAPosPV, float); +DECLARE_SOA_COLUMN(Photon1DCANegPV, photon1DCANegPV, float); +DECLARE_SOA_COLUMN(Photon1DCADau, photon1DCADau, float); +DECLARE_SOA_COLUMN(Photon1NegEta, photon1NegEta, float); +DECLARE_SOA_COLUMN(Photon1PosEta, photon1PosEta, float); +DECLARE_SOA_COLUMN(Photon1CosPA, photon1CosPA, float); +DECLARE_SOA_COLUMN(Photon1Radius, photon1Radius, float); +DECLARE_SOA_COLUMN(Photon1Zconv, photon1Zconv, float); +DECLARE_SOA_COLUMN(Photon1PosTPCCrossedRows, photon1PosTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon1NegTPCCrossedRows, photon1NegTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon1PosTPCNSigmaEl, photon1PosTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon1NegTPCNSigmaEl, photon1NegTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon1V0Type, photon1V0Type, uint8_t); + +DECLARE_SOA_COLUMN(Photon2Px, photon2Px, float); +DECLARE_SOA_COLUMN(Photon2Py, photon2Py, float); +DECLARE_SOA_COLUMN(Photon2Pz, photon2Pz, float); +DECLARE_SOA_COLUMN(Photon2Mass, photon2Mass, float); +DECLARE_SOA_COLUMN(Photon2Qt, photon2Qt, float); +DECLARE_SOA_COLUMN(Photon2Alpha, photon2Alpha, float); +DECLARE_SOA_COLUMN(Photon2DCAPosPV, photon2DCAPosPV, float); +DECLARE_SOA_COLUMN(Photon2DCANegPV, photon2DCANegPV, float); +DECLARE_SOA_COLUMN(Photon2DCADau, photon2DCADau, float); +DECLARE_SOA_COLUMN(Photon2NegEta, photon2NegEta, float); +DECLARE_SOA_COLUMN(Photon2PosEta, photon2PosEta, float); +DECLARE_SOA_COLUMN(Photon2CosPA, photon2CosPA, float); +DECLARE_SOA_COLUMN(Photon2Radius, photon2Radius, float); +DECLARE_SOA_COLUMN(Photon2Zconv, photon2Zconv, float); +DECLARE_SOA_COLUMN(Photon2PosTPCCrossedRows, photon2PosTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon2NegTPCCrossedRows, photon2NegTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon2PosTPCNSigmaEl, photon2PosTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon2NegTPCNSigmaEl, photon2NegTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon2V0Type, photon2V0Type, uint8_t); + +//______________________________________________________ +// DYNAMIC COLUMNS +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Pi0 px + [](float photon1Px, float photon2Px) -> float { return photon1Px + photon2Px; }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Pi0 py + [](float photon1Py, float photon2Py) -> float { return photon1Py + photon2Py; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Pi0 pz + [](float photon1Pz, float photon2Pz) -> float { return photon1Pz + photon2Pz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, + [](float photon1Px, float photon1Py, float photon2Px, float photon2Py) -> float { + return RecoDecay::pt(array{photon1Px + photon2Px, photon1Py + photon2Py}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Total momentum in GeV/c + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1Px + photon2Px, photon1Py + photon2Py, photon1Pz + photon2Pz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0Mass, pi0Mass, + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + std::array pVecPhoton1{photon1Px, photon1Py, photon1Pz}; + std::array pVecPhoton2{photon2Px, photon2Py, photon2Pz}; + auto arrMom = std::array{pVecPhoton1, pVecPhoton2}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0Y, pi0Y, + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::y(std::array{photon1Px + photon2Px, photon1Py + photon2Py, photon1Pz + photon2Pz}, o2::constants::physics::MassPi0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Phi in the range [0, 2pi) + [](float photon1Px, float photon1Py, float photon2Px, float photon2Py) -> float { return RecoDecay::phi(photon1Px + photon2Px, photon1Py + photon2Py); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Pseudorapidity + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::eta(std::array{photon1Px + photon2Px, photon1Py + photon2Py, photon1Pz + photon2Pz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Radius, radius, //! Pi0 decay radius (2D, centered at zero) + [](float x, float y) -> float { return RecoDecay::sqrtSumOfSquares(x, y); }); + +DECLARE_SOA_DYNAMIC_COLUMN(OPAngle, opAngle, + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) { + TVector3 v1(photon1Px, photon1Py, photon1Pz); + TVector3 v2(photon2Px, photon2Py, photon2Pz); + return v1.Angle(v2); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Pt, photon1Pt, //! Transverse momentum in GeV/c + [](float photon1Px, float photon1Py) -> float { + return RecoDecay::sqrtSumOfSquares(photon1Px, photon1Py); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1P, photon1p, //! Total momentum in GeV/c + [](float photon1Px, float photon1Py, float photon1Pz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1Px, photon1Py, photon1Pz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Eta, photon1Eta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon1Px, float photon1Py, float photon1Pz) -> float { + return RecoDecay::eta(std::array{photon1Px, photon1Py, photon1Pz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Y, photon1Y, //! Rapidity + [](float photon1Px, float photon1Py, float photon1Pz) -> float { + return RecoDecay::y(std::array{photon1Px, photon1Py, photon1Pz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Phi, photon1Phi, //! Phi in the range [0, 2pi) + [](float photon1Px, float photon1Py) -> float { return RecoDecay::phi(photon1Px, photon1Py); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Pt, photon2Pt, //! Transverse momentum in GeV/c + [](float photon2Px, float photon2Py) -> float { + return RecoDecay::sqrtSumOfSquares(photon2Px, photon2Py); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2P, photon2p, //! Total momentum in GeV/c + [](float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::sqrtSumOfSquares(photon2Px, photon2Py, photon2Pz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Eta, photon2Eta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::eta(std::array{photon2Px, photon2Py, photon2Pz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Y, photon2Y, //! Rapidity + [](float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::y(std::array{photon2Px, photon2Py, photon2Pz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Phi, photon2Phi, //! Phi in the range [0, 2pi) + [](float photon2Px, float photon2Py) -> float { return RecoDecay::phi(photon2Px, photon2Py); }); + +} // namespace Pi0Core + +DECLARE_SOA_TABLE(Pi0Cores, "AOD", "PI0CORES", + Pi0Core::X, Pi0Core::Y, Pi0Core::Z, Pi0Core::DCADaughters, Pi0Core::CosPA, + + // Photon 1 base properties + Pi0Core::Photon1Px, Pi0Core::Photon1Py, Pi0Core::Photon1Pz, + Pi0Core::Photon1Mass, Pi0Core::Photon1Qt, Pi0Core::Photon1Alpha, Pi0Core::Photon1DCAPosPV, Pi0Core::Photon1DCANegPV, Pi0Core::Photon1DCADau, + Pi0Core::Photon1NegEta, Pi0Core::Photon1PosEta, Pi0Core::Photon1CosPA, Pi0Core::Photon1Radius, Pi0Core::Photon1Zconv, + Pi0Core::Photon1PosTPCCrossedRows, Pi0Core::Photon1NegTPCCrossedRows, Pi0Core::Photon1PosTPCNSigmaEl, Pi0Core::Photon1NegTPCNSigmaEl, Pi0Core::Photon1V0Type, + + // Photon 2 base properties + Pi0Core::Photon2Px, Pi0Core::Photon2Py, Pi0Core::Photon2Pz, + Pi0Core::Photon2Mass, Pi0Core::Photon2Qt, Pi0Core::Photon2Alpha, Pi0Core::Photon2DCAPosPV, Pi0Core::Photon2DCANegPV, Pi0Core::Photon2DCADau, + Pi0Core::Photon2NegEta, Pi0Core::Photon2PosEta, Pi0Core::Photon2CosPA, Pi0Core::Photon2Radius, Pi0Core::Photon2Zconv, + Pi0Core::Photon2PosTPCCrossedRows, Pi0Core::Photon2NegTPCCrossedRows, Pi0Core::Photon2PosTPCNSigmaEl, Pi0Core::Photon2NegTPCNSigmaEl, Pi0Core::Photon2V0Type, + + // Dynamic columns + Pi0Core::Px, + Pi0Core::Py, + Pi0Core::Pz, + Pi0Core::Pt, + Pi0Core::P, + Pi0Core::Pi0Mass, + Pi0Core::Pi0Y, + Pi0Core::Phi, + Pi0Core::Eta, + Pi0Core::Radius, + Pi0Core::OPAngle, + + Pi0Core::Photon1Pt, + Pi0Core::Photon1P, + Pi0Core::Photon1Eta, + Pi0Core::Photon1Y, + Pi0Core::Photon1Phi, + + Pi0Core::Photon2Pt, + Pi0Core::Photon2P, + Pi0Core::Photon2Eta, + Pi0Core::Photon2Y, + Pi0Core::Photon2Phi); + +// for MC +namespace Pi0CoreMC +{ + +DECLARE_SOA_COLUMN(MCradius, mcradius, float); +DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); +DECLARE_SOA_COLUMN(PDGCodeMother, pdgCodeMother, int); +DECLARE_SOA_COLUMN(MCprocess, mcprocess, int); +DECLARE_SOA_COLUMN(IsProducedByGenerator, isProducedByGenerator, bool); + +DECLARE_SOA_COLUMN(Photon1MCPx, photon1mcpx, float); +DECLARE_SOA_COLUMN(Photon1MCPy, photon1mcpy, float); +DECLARE_SOA_COLUMN(Photon1MCPz, photon1mcpz, float); +DECLARE_SOA_COLUMN(IsPhoton1Primary, isPhoton1Primary, bool); +DECLARE_SOA_COLUMN(Photon1PDGCode, photon1PDGCode, int); +DECLARE_SOA_COLUMN(Photon1PDGCodeMother, photon1PDGCodeMother, int); +DECLARE_SOA_COLUMN(Photon1IsCorrectlyAssoc, photon1IsCorrectlyAssoc, bool); + +DECLARE_SOA_COLUMN(Photon2MCPx, photon2mcpx, float); +DECLARE_SOA_COLUMN(Photon2MCPy, photon2mcpy, float); +DECLARE_SOA_COLUMN(Photon2MCPz, photon2mcpz, float); +DECLARE_SOA_COLUMN(IsPhoton2Primary, isPhoton2Primary, bool); +DECLARE_SOA_COLUMN(Photon2PDGCode, photon2PDGCode, int); +DECLARE_SOA_COLUMN(Photon2PDGCodeMother, photon2PDGCodeMother, int); +DECLARE_SOA_COLUMN(Photon2IsCorrectlyAssoc, photon2IsCorrectlyAssoc, bool); + +DECLARE_SOA_DYNAMIC_COLUMN(IsPi0, isPi0, //! IsPi0 + [](int pdgCode) -> bool { return pdgCode == 111; }); + +DECLARE_SOA_DYNAMIC_COLUMN(IsFromXi0, isFromXi0, //! Pi0 from Xi0 + [](int pdgCodeMother) -> bool { return pdgCodeMother == 3322; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPx, mcpx, //! Pi0 MC px + [](float photon1MCPx, float photon2MCPx) -> float { return photon1MCPx + photon2MCPx; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPy, mcpy, //! Pi0 MC py + [](float photon1MCPy, float photon2MCPy) -> float { return photon1MCPy + photon2MCPy; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPz, mcpz, //! Pi0 MC pz + [](float photon1MCPz, float photon2MCPz) -> float { return photon1MCPz + photon2MCPz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPt, mcpt, + [](float photon1MCPx, float photon1MCPy, float photon2MCPx, float photon2MCPy) -> float { + return RecoDecay::pt(array{photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCP, mcp, //! Total momentum in GeV/c + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy, photon1MCPz + photon2MCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0MCMass, pi0MCMass, + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + std::array pVecPhoton1{photon1MCPx, photon1MCPy, photon1MCPz}; + std::array pVecPhoton2{photon2MCPx, photon2MCPy, photon2MCPz}; + auto arrMom = std::array{pVecPhoton1, pVecPhoton2}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0MCY, pi0MCY, + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::y(std::array{photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy, photon1MCPz + photon2MCPz}, o2::constants::physics::MassPi0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPhi, mcphi, //! Phi in the range [0, 2pi) + [](float photon1MCPx, float photon1MCPy, float photon2MCPx, float photon2MCPy) -> float { return RecoDecay::phi(photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCEta, mceta, //! Pseudorapidity + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::eta(std::array{photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy, photon1MCPz + photon2MCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCOPAngle, mcopAngle, + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) { + TVector3 v1(photon1MCPx, photon1MCPy, photon1MCPz); + TVector3 v2(photon2MCPx, photon2MCPy, photon2MCPz); + return v1.Angle(v2); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCPt, photon1MCPt, //! Transverse momentum in GeV/c + [](float photon1MCPx, float photon1MCPy) -> float { + return RecoDecay::sqrtSumOfSquares(photon1MCPx, photon1MCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCP, photon1MCp, //! Total momentum in GeV/c + [](float photon1MCPx, float photon1MCPy, float photon1MCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1MCPx, photon1MCPy, photon1MCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCEta, photon1MCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon1MCPx, float photon1MCPy, float photon1MCPz) -> float { + return RecoDecay::eta(std::array{photon1MCPx, photon1MCPy, photon1MCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCY, photon1MCY, //! Rapidity + [](float photon1MCPx, float photon1MCPy, float photon1MCPz) -> float { + return RecoDecay::y(std::array{photon1MCPx, photon1MCPy, photon1MCPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCPhi, photon1MCPhi, //! Phi in the range [0, 2pi) + [](float photon1MCPx, float photon1MCPy) -> float { return RecoDecay::phi(photon1MCPx, photon1MCPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCPt, photon2MCPt, //! Transverse momentum in GeV/c + [](float photon2MCPx, float photon2MCPy) -> float { + return RecoDecay::sqrtSumOfSquares(photon2MCPx, photon2MCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCP, photon2MCp, //! Total momentum in GeV/c + [](float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photon2MCPx, photon2MCPy, photon2MCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCEta, photon2MCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::eta(std::array{photon2MCPx, photon2MCPy, photon2MCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCY, photon2MCY, //! Rapidity + [](float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::y(std::array{photon2MCPx, photon2MCPy, photon2MCPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCPhi, photon2MCPhi, //! Phi in the range [0, 2pi) + [](float photon2MCPx, float photon2MCPy) -> float { return RecoDecay::phi(photon2MCPx, photon2MCPy); }); + +} // namespace Pi0CoreMC + +DECLARE_SOA_TABLE(Pi0CoresMC, "AOD", "PI0CORESMC", + // Basic properties + Pi0CoreMC::MCradius, Pi0CoreMC::PDGCode, Pi0CoreMC::PDGCodeMother, Pi0CoreMC::MCprocess, Pi0CoreMC::IsProducedByGenerator, + + Pi0CoreMC::Photon1MCPx, Pi0CoreMC::Photon1MCPy, Pi0CoreMC::Photon1MCPz, + Pi0CoreMC::IsPhoton1Primary, Pi0CoreMC::Photon1PDGCode, Pi0CoreMC::Photon1PDGCodeMother, Pi0CoreMC::Photon1IsCorrectlyAssoc, + + Pi0CoreMC::Photon2MCPx, Pi0CoreMC::Photon2MCPy, Pi0CoreMC::Photon2MCPz, + Pi0CoreMC::IsPhoton2Primary, Pi0CoreMC::Photon2PDGCode, Pi0CoreMC::Photon2PDGCodeMother, Pi0CoreMC::Photon2IsCorrectlyAssoc, + + // Dynamic columns + Pi0CoreMC::IsPi0, + Pi0CoreMC::IsFromXi0, + + Pi0CoreMC::MCPx, + Pi0CoreMC::MCPy, + Pi0CoreMC::MCPz, + Pi0CoreMC::MCPt, + Pi0CoreMC::MCP, + Pi0CoreMC::Pi0MCMass, + Pi0CoreMC::Pi0MCY, + Pi0CoreMC::MCPhi, + Pi0CoreMC::MCEta, + Pi0CoreMC::MCOPAngle, + + Pi0CoreMC::Photon1MCPt, + Pi0CoreMC::Photon1MCP, + Pi0CoreMC::Photon1MCEta, + Pi0CoreMC::Photon1MCY, + Pi0CoreMC::Photon1MCPhi, + + Pi0CoreMC::Photon2MCPt, + Pi0CoreMC::Photon2MCP, + Pi0CoreMC::Photon2MCEta, + Pi0CoreMC::Photon2MCY, + Pi0CoreMC::Photon2MCPhi); + +DECLARE_SOA_TABLE(Pi0CollRef, "AOD", "PI0COLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraCollisionId); + +namespace pi0Gen +{ +DECLARE_SOA_COLUMN(ProducedByGenerator, producedByGenerator, bool); +DECLARE_SOA_COLUMN(Pi0MCPt, pi0MCPt, float); // MC pT +} // namespace pi0Gen + +DECLARE_SOA_TABLE(Pi0Gens, "AOD", "PI0GENS", + pi0Gen::ProducedByGenerator, + pi0Gen::Pi0MCPt); + +DECLARE_SOA_TABLE(Pi0GenCollRef, "AOD", "PI0GENCOLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraMCCollisionId); + } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSIGMATABLES_H_ diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index bcd914b3df3..633dd9dbb96 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -501,7 +501,8 @@ struct decay3bodyBuilder { auto timestamp = bc.timestamp(); o2::parameters::GRPMagField* grpmag = 0x0; - grpmag = ccdb->getForTimeStamp(ccdbConfigurations.grpmagPath, timestamp); + ccdb->clearCache(ccdbConfigurations.grpmagPath); + grpmag = ccdb->getSpecific(ccdbConfigurations.grpmagPath, timestamp); if (!grpmag) { LOG(fatal) << "Got nullptr from CCDB for path " << ccdbConfigurations.grpmagPath << " of object GRPMagField for timestamp " << timestamp; } diff --git a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx index bdb0c4a2058..8c1c58e272a 100644 --- a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx +++ b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx @@ -201,6 +201,7 @@ struct EbyeMaker { Configurable etaMaxV0dau{"etaMaxV0dau", 0.8f, "maximum eta V0 daughters"}; Configurable outerPIDMin{"outerPIDMin", -4.f, "minimum outer PID"}; + Configurable countOnlyNegTrk{"countOnlyNegTrk", false, "count only negative tracks in Ntracks"}; Configurable useAllEvSel{"useAllEvSel", false, "use additional event selections fo run 3 analyses"}; Configurable triggerCut{"triggerCut", 0x0, "trigger cut to select"}; Configurable kINT7Intervals{"kINT7Intervals", false, "toggle kINT7 trigger selection in the 10-30% and 50-90% centrality intervals (2018 Pb-Pb)"}; @@ -256,7 +257,6 @@ struct EbyeMaker { Configurable antidItsClsSizeCut{"antidItsClsSizeCut", 1.e-10f, "cluster size cut for antideuterons"}; Configurable antidPtItsClsSizeCut{"antidPtItsClsSizeCut", 10.f, "pt for cluster size cut for antideuterons"}; - Configurable trklEtaMax{"trklEtaMax", 0.8f, "maximum eta for run 2 tracklets"}; Configurable> cfgTrackSels{"cfgTrackSels", {kTrackSels, 1, 12, particleName, trackSelsNames}, "Track selections"}; std::array ptMin; @@ -553,9 +553,9 @@ struct EbyeMaker { std::array dcaInfo; for (const auto& track : tracks) { - if (track.trackType() == o2::aod::track::TrackTypeEnum::Run2Tracklet && std::abs(track.eta()) < trklEtaMax && !(doprocessRun3 || doprocessMcRun3)) { // tracklet + if (track.trackType() == o2::aod::track::TrackTypeEnum::Run2Tracklet && std::abs(track.eta()) < etaMax && !(doprocessRun3 || doprocessMcRun3)) { // tracklet nTrackletsColl++; - } else if (std::abs(track.eta()) < trklEtaMax && track.itsNCls() > 3 && (doprocessRun3 || doprocessMcRun3)) { // ITS only + global tracks + } else if (std::abs(track.eta()) < etaMax && track.itsNCls() > 3 && (doprocessRun3 || doprocessMcRun3)) { // ITS only + global tracks nTrackletsColl++; } if (!selectTrack(track)) { @@ -571,7 +571,7 @@ struct EbyeMaker { continue; } histos.fill(HIST("QA/tpcSignal"), track.tpcInnerParam(), track.tpcSignal()); - if (trackPt > ptMin[0] && trackPt < ptMax[0]) + if (trackPt > ptMin[0] && trackPt < ptMax[0] && ((track.sign() < 0 && countOnlyNegTrk) || !countOnlyNegTrk)) nTracksColl++; for (int iP{0}; iP < kNpart; ++iP) { @@ -854,8 +854,11 @@ struct EbyeMaker { continue; auto pdgCode = mcPart.pdgCode(); auto genPt = std::hypot(mcPart.px(), mcPart.py()); - if ((std::abs(pdgCode) == PDG_t::kPiPlus || std::abs(pdgCode) == PDG_t::kElectron || std::abs(pdgCode) == PDG_t::kMuonMinus || std::abs(pdgCode) == PDG_t::kKPlus || std::abs(pdgCode) == PDG_t::kProton) && mcPart.isPhysicalPrimary() && genPt > ptMin[0] && genPt < ptMax[0]) - nChPartGen++; + if ((std::abs(pdgCode) == PDG_t::kPiPlus || std::abs(pdgCode) == PDG_t::kElectron || std::abs(pdgCode) == PDG_t::kMuonMinus || std::abs(pdgCode) == PDG_t::kKPlus || std::abs(pdgCode) == PDG_t::kProton) && mcPart.isPhysicalPrimary() && genPt > ptMin[0] && genPt < ptMax[0]) { + int ch = (pdgCode == PDG_t::kPiPlus || pdgCode == -PDG_t::kElectron || pdgCode == -PDG_t::kMuonMinus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton) ? 1 : -1; + if ((ch < 0 && countOnlyNegTrk) || !countOnlyNegTrk) + nChPartGen++; + } if (std::abs(pdgCode) == PDG_t::kLambda0) { if (!mcPart.isPhysicalPrimary() && !mcPart.has_mothers()) continue; diff --git a/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx index 4c7ac865c18..ef26c0f7b06 100644 --- a/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx @@ -70,8 +70,6 @@ constexpr int kITSLayers = 7; constexpr int kITSInnerBarrelLayers = 3; // constexpr int kITSOuterBarrelLayers = 4; -const std::array covPosSV{6.4462712107237135f, 0.1309793068144521f, 6.626654155592929f, -0.4510297694023185f, 0.16996629627762413f, 4.109195981415627f}; - std::shared_ptr hMothCounter; std::shared_ptr hDaugCounter; std::shared_ptr hDaugTPCNSigma; @@ -320,35 +318,6 @@ float getTPCNSigma(const TTrack& track, o2::track::PID partType) return nSigma; } -//-------------------------------------------------------------- -// Refit the momentum of the mother track -template -bool refitMotherTrack(const TTrack& track, o2::track::TrackParametrizationWithError& trackPar, const o2::dataformats::VertexBase& primaryVtx, const o2::dataformats::VertexBase& secondaryVtx) -{ - float trackIUPos[2] = {track.y(), track.z()}; - float trackIUCov[3] = {track.cYY(), track.cZY(), track.cZZ()}; - - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, trackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - - trackPar.resetCovariance(1e15); - if (!trackPar.update(primaryVtx)) { - return false; - } - - trackPar.rotate(track.alpha()); - o2::base::Propagator::Instance()->PropagateToXBxByBz(trackPar, track.x()); - if (!trackPar.update(trackIUPos, trackIUCov)) { - return false; - } - - o2::base::Propagator::Instance()->propagateToDCABxByBz(secondaryVtx, trackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - if (!trackPar.update(secondaryVtx)) { - return false; - } - - return true; -} - //-------------------------------------------------------------- struct HypKinkCandidate { @@ -367,6 +336,9 @@ struct HypKinkCandidate { float chi2ITSMoth = 0.0f; uint32_t itsClusterSizeMoth = 0u; uint32_t itsClusterSizeDaug = 0u; + float tpcMomDaug = -999.f; + float tpcSignalDaug = -999.f; + int16_t tpcNClsPIDDaug = 0u; float nSigmaTPCDaug = -999.f; float nSigmaITSDaug = -999.f; float nSigmaTOFDaug = -999.f; // recalculated TOF NSigma @@ -409,6 +381,11 @@ struct HyperkinkRecoTask { Configurable cutTPCNSigmaDaug{"cutTPCNSigmaDaug", 5, "TPC NSigma cut for daughter tracks"}; Configurable cutTOFNSigmaDaug{"cutTOFNSigmaDaug", 1000, "TOF NSigma cut for daughter tracks"}; Configurable askTOFForDaug{"askTOFForDaug", false, "If true, ask for TOF signal"}; + Configurable minDaugPt{"minDaugPt", 1.0f, "Minimum pT of daughter track (GeV/c)"}; + Configurable minDCADaugToPV{"minDCADaugToPV", 0.f, "Minimum DCA of daughter track to primary vertex (cm)"}; + Configurable maxDCADaugToPV{"maxDCADaugToPV", 999.0f, "Maximum DCA of daughter track to primary vertex (cm)"}; + Configurable maxQtAP{"maxQtAP", 1.f, "Maximum qT of Armenteros-Podolanski Plot"}; + Configurable maxDCAKinkTopo{"maxDCAKinkTopo", 1.f, "Maximum DCA of kink topology (cm)"}; // CCDB options Configurable inputBz{"inputBz", -999, "bz field, -999 is automatic"}; @@ -422,6 +399,7 @@ struct HyperkinkRecoTask { o2::aod::ITSResponse itsResponse; + float massMoth = 999.f; float massChargedDaug = 999.f; float massNeutralDaug = 999.f; int pdgMoth = 0; @@ -438,6 +416,7 @@ struct HyperkinkRecoTask { void init(InitContext& initContext) { if (hypoMoth == kHypertriton) { + massMoth = o2::constants::physics::MassHyperTriton; massChargedDaug = o2::constants::physics::MassTriton; massNeutralDaug = o2::constants::physics::MassPi0; pdgMoth = o2::constants::physics::Pdg::kHyperTriton; @@ -445,6 +424,7 @@ struct HyperkinkRecoTask { pdgDaug[kDaugNeutral] = PDG_t::kPi0; pidTypeDaug = o2::track::PID::Triton; } else if (hypoMoth == kHyperhelium4sigma) { + massMoth = o2::constants::physics::MassHyperHelium4Sigma; massChargedDaug = o2::constants::physics::MassAlpha; massNeutralDaug = o2::constants::physics::MassPi0; pdgMoth = o2::constants::physics::Pdg::kHyperHelium4Sigma; @@ -463,27 +443,28 @@ struct HyperkinkRecoTask { if (hypoMoth == kHyperhelium4sigma) { massAxis = AxisSpec{100, 3.85, 4.25, "m (GeV/#it{c}^{2})"}; } - const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta #it{p}_{T} (GeV/#it{c})"}; - const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta #it{p}_{z} (GeV/#it{c})"}; - const AxisSpec radiusAxis{40, 0.f, 40.f, "R (cm)"}; + const AxisSpec deltaPtAxis{200, -10.f, 10.f, "#Delta #it{p}_{T} (GeV/#it{c})"}; + const AxisSpec deltaPzAxis{200, -10.f, 10.f, "#Delta #it{p}_{z} (GeV/#it{c})"}; + const AxisSpec recRadiusAxis{40, 0.f, 40.f, "Rec SV R (cm)"}; registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{2, 0, 2}}); registry.add("hVertexZCollision", "hVertexZCollision", HistType::kTH1F, {vertexZAxis}); - registry.add("hCandidateCounter", "hCandidateCounter", HistType::kTH1F, {{4, 0, 4}}); + registry.add("hCandidateCounter", "hCandidateCounter", HistType::kTH1F, {{8, 0, 8}}); if (doprocessMC == true) { itsResponse.setMCDefaultParameters(); - registry.add("hTrueCandidateCounter", "hTrueCandidateCounter", HistType::kTH1F, {{4, 0, 4}}); - registry.add("hDiffSVx", ";#Delta x (cm);", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDiffSVy", ";#Delta y (cm);", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDiffSVz", ";#Delta z (cm);", HistType::kTH1F, {{200, -10, 10}}); - registry.add("h2RecSVRVsTrueSVR", ";Reconstruced SV R (cm);True SV R (cm);", HistType::kTH2F, {radiusAxis, radiusAxis}); - registry.add("h2TrueMotherDiffPtVsRecSVR", ";Reconstruced SV R (cm);#Delta #it{p}_{T} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPtAxis}); - registry.add("h2TrueMotherDiffEtaVsRecSVR", ";Reconstruced SV R (cm);#Delta #eta;", HistType::kTH2F, {radiusAxis, {200, -0.1, 0.1}}); - registry.add("hDiffDauPx", ";#Delta p_{x} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); - registry.add("hDiffDauPy", ";#Delta p_{y} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); - registry.add("hDiffDauPz", ";#Delta p_{z} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); + registry.add("hTrueCandidateCounter", "hTrueCandidateCounter", HistType::kTH1F, {{8, 0, 8}}); + registry.add("hDeltaSVx", ";#Delta x (cm);", HistType::kTH1F, {{200, -2, 2}}); + registry.add("hDeltaSVy", ";#Delta y (cm);", HistType::kTH1F, {{200, -2, 2}}); + registry.add("hDeltaSVz", ";#Delta z (cm);", HistType::kTH1F, {{200, -2, 2}}); + registry.add("hDeltaSVRVsTrueSVR", ";True SVR (cm);#Delta R (cm)", HistType::kTH2F, {{200, 0, 40}, {200, -2, 2}}); + registry.add("h2RecSVRVsTrueSVR", ";Rec SV R (cm);True SV R (cm);", HistType::kTH2F, {recRadiusAxis, {40, 0, 40}}); + registry.add("h2TrueMotherDeltaPtVsRecSVR", ";Rec SV R (cm);#Delta #it{p}_{T} (GeV/#it{c});", HistType::kTH2F, {recRadiusAxis, deltaPtAxis}); + registry.add("h2TrueMotherDeltaEtaVsRecSVR", ";Rec SV R (cm);#Delta #eta;", HistType::kTH2F, {recRadiusAxis, {200, -0.1, 0.1}}); + registry.add("hDeltaDauPx", ";#Delta p_{x} (GeV/#it{c}); ", HistType::kTH1F, {{200, -2, 2}}); + registry.add("hDeltaDauPy", ";#Delta p_{y} (GeV/#it{c}); ", HistType::kTH1F, {{200, -2, 2}}); + registry.add("hDeltaDauPz", ";#Delta p_{z} (GeV/#it{c}); ", HistType::kTH1F, {{200, -2, 2}}); registry.add("h2TrueSignalMassPt", "h2TrueSignalMassPt", HistType::kTH2F, {{ptAxis, massAxis}}); registry.add("h2TrueDaugTPCNSigmaPt", "h2TrueDaugTPCNSigmaPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); @@ -494,11 +475,15 @@ struct HyperkinkRecoTask { registry.add("hDaugOldTOFNSigma_WrongCol", "hDaugOldTOFNSigma_WrongCol", HistType::kTH1F, {{600, -300, 300}}); registry.add("hDaugNewTOFNSigma_CorrectCol", "hDaugNewTOFNSigma_CorrectCol", HistType::kTH1F, {{600, -300, 300}}); registry.add("hDaugNewTOFNSigma_WrongCol", "hDaugNewTOFNSigma_WrongCol", HistType::kTH1F, {{600, -300, 300}}); + + registry.add("hTrueSignalInvMassNegNeutDaugE", "hTrueSignalInvMassNegNeutDaugE", HistType::kTH1F, {{1000, 2.8, 4, "m (GeV/#it{c}^{2})"}}); } registry.add("h2MothMassPt", "h2MothMassPt", HistType::kTH2F, {{ptAxis, massAxis}}); registry.add("h2DaugTPCNSigmaPt", "h2DaugTPCNSigmaPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); + registry.add("hInvMassNegNeutDaugE", "hInvMassNegNeutDaugE", HistType::kTH1F, {{1000, 2.8, 4, "m (GeV/#it{c}^{2})"}}); + ccdb->setURL(ccdbPath); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -573,6 +558,9 @@ struct HyperkinkRecoTask { fillCandidateRecoMoth(hypkinkCand, collision, trackMoth); hypkinkCand.itsClusterSizeDaug = trackDaug.itsClusterSizes(); + hypkinkCand.tpcMomDaug = trackDaug.tpcInnerParam() * trackDaug.sign(); + hypkinkCand.tpcSignalDaug = trackDaug.tpcSignal(); + hypkinkCand.tpcNClsPIDDaug = trackDaug.tpcNClsPID(); hypkinkCand.nSigmaTPCDaug = getTPCNSigma(trackDaug, pidTypeDaug); hypkinkCand.nSigmaITSDaug = getITSNSigma(trackDaug, itsResponse, pidTypeDaug); @@ -659,10 +647,7 @@ struct HyperkinkRecoTask { if (std::abs(tpcNSigmaDaug) > cutTPCNSigmaDaug) { continue; } - float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{massChargedDaug, massNeutralDaug}); registry.fill(HIST("hCandidateCounter"), 2); - registry.fill(HIST("h2MothMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); - registry.fill(HIST("h2DaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); auto bc = collision.bc_as(); initCCDB(bc); @@ -675,23 +660,40 @@ struct HyperkinkRecoTask { if ((daugTrack.hasTOF() || askTOFForDaug) && std::abs(nSigmaTOF) > cutTOFNSigmaDaug) { continue; } + registry.fill(HIST("hCandidateCounter"), 3); + + if (kinkCand.ptDaug() < minDaugPt) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 4); + + if (std::abs(kinkCand.dcaDaugPv()) < minDCADaugToPV || std::abs(kinkCand.dcaDaugPv()) > maxDCADaugToPV) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 5); + + if (kinkCand.dcaKinkTopo() > maxDCAKinkTopo) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 6); + + float p2Moth = kinkCand.pxMoth() * kinkCand.pxMoth() + kinkCand.pyMoth() * kinkCand.pyMoth() + kinkCand.pzMoth() * kinkCand.pzMoth(); + float p2Daug = kinkCand.pxDaug() * kinkCand.pxDaug() + kinkCand.pyDaug() * kinkCand.pyDaug() + kinkCand.pzDaug() * kinkCand.pzDaug(); + float sqKink = kinkCand.pxMoth() * kinkCand.pxDaug() + kinkCand.pyMoth() * kinkCand.pyDaug() + kinkCand.pzMoth() * kinkCand.pzDaug(); + float qt = std::sqrt(p2Daug - sqKink * sqKink / p2Moth); + if (qt > maxQtAP) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 7); + + float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{massChargedDaug, massNeutralDaug}); + registry.fill(HIST("h2MothMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); + registry.fill(HIST("h2DaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); - registry.fill(HIST("hCandidateCounter"), 2); HypKinkCandidate hypkinkCand; fillCandidate(hypkinkCand, collision, kinkCand, motherTrack, daugTrack); hypkinkCand.nSigmaTOFDaug = nSigmaTOF; - o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; - o2::dataformats::VertexBase secondaryVtx = {{kinkCand.xDecVtx() + collision.posX(), kinkCand.yDecVtx() + collision.posY(), kinkCand.zDecVtx() + collision.posZ()}, {covPosSV[0], covPosSV[1], covPosSV[2], covPosSV[3], covPosSV[4], covPosSV[5]}}; - std::array refitPPV = {-999.f}; - std::array refitPSV = {-999.f}; - auto motherTrackPar = getTrackParCov(motherTrack); - if (refitMotherTrack(motherTrack, motherTrackPar, primaryVtx, secondaryVtx)) { - motherTrackPar.getPxPyPzGlo(refitPSV); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - motherTrackPar.getPxPyPzGlo(refitPPV); - } - outputDataTable( mBz > 0 ? 1 : -1, hypkinkCand.posPV[0], hypkinkCand.posPV[1], hypkinkCand.posPV[2], @@ -699,11 +701,10 @@ struct HyperkinkRecoTask { hypkinkCand.isMatter, hypkinkCand.lastPosMoth[0], hypkinkCand.lastPosMoth[1], hypkinkCand.lastPosMoth[2], hypkinkCand.momMothSV[0], hypkinkCand.momMothSV[1], hypkinkCand.momMothSV[2], - refitPPV[0], refitPPV[1], refitPPV[2], - refitPSV[0], refitPSV[1], refitPSV[2], hypkinkCand.momDaugSV[0], hypkinkCand.momDaugSV[1], hypkinkCand.momDaugSV[2], hypkinkCand.dcaXYMothPv, hypkinkCand.dcaXYDaugPv, hypkinkCand.dcaKinkTopo, hypkinkCand.chi2ITSMoth, hypkinkCand.itsClusterSizeMoth, hypkinkCand.itsClusterSizeDaug, + hypkinkCand.tpcMomDaug, hypkinkCand.tpcSignalDaug, hypkinkCand.tpcNClsPIDDaug, hypkinkCand.nSigmaTPCDaug, hypkinkCand.nSigmaITSDaug, hypkinkCand.nSigmaTOFDaug, hypkinkCand.momMothPV[0], hypkinkCand.momMothPV[1], hypkinkCand.momMothPV[2], hypkinkCand.updateMomMothPV[0], hypkinkCand.updateMomMothPV[1], hypkinkCand.updateMomMothPV[2]); @@ -744,7 +745,9 @@ struct HyperkinkRecoTask { if (hypoMoth == kHypertriton) { auto dChannel = H3LDecay::getDecayChannel(mcMothTrack, dauIDList); if (dChannel == H3LDecay::k2bodyNeutral && dauIDList[0] == mcDaugTrack.globalIndex()) { - isKinkSignal = true; + if (std::hypot(mcDaugTrack.vx(), mcDaugTrack.vy()) > LayerRadii[3]) { + isKinkSignal = true; + } } } else if (hypoMoth == kHyperhelium4sigma) { auto dChannel = He4SDecay::getDecayChannel(mcMothTrack, dauIDList); @@ -771,13 +774,10 @@ struct HyperkinkRecoTask { if (std::abs(tpcNSigmaDaug) > cutTPCNSigmaDaug) { continue; } - float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{massChargedDaug, massNeutralDaug}); registry.fill(HIST("hCandidateCounter"), 2); if (isKinkSignal) { registry.fill(HIST("hTrueCandidateCounter"), 2); } - registry.fill(HIST("h2MothMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); - registry.fill(HIST("h2DaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); auto bc = collision.bc_as(); initCCDB(bc); @@ -802,38 +802,81 @@ struct HyperkinkRecoTask { registry.fill(HIST("hTrueCandidateCounter"), 3); } + if (kinkCand.ptDaug() < minDaugPt) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 4); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 4); + } + + if (std::abs(kinkCand.dcaDaugPv()) < minDCADaugToPV || std::abs(kinkCand.dcaDaugPv()) > maxDCADaugToPV) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 5); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 5); + } + + if (kinkCand.dcaKinkTopo() > maxDCAKinkTopo) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 6); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 6); + } + + float p2Moth = kinkCand.pxMoth() * kinkCand.pxMoth() + kinkCand.pyMoth() * kinkCand.pyMoth() + kinkCand.pzMoth() * kinkCand.pzMoth(); + float p2Daug = kinkCand.pxDaug() * kinkCand.pxDaug() + kinkCand.pyDaug() * kinkCand.pyDaug() + kinkCand.pzDaug() * kinkCand.pzDaug(); + float sqKink = kinkCand.pxMoth() * kinkCand.pxDaug() + kinkCand.pyMoth() * kinkCand.pyDaug() + kinkCand.pzMoth() * kinkCand.pzDaug(); + float qt = std::sqrt(p2Daug - sqKink * sqKink / p2Moth); + if (qt > maxQtAP) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 7); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 7); + } + + float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{massChargedDaug, massNeutralDaug}); + registry.fill(HIST("h2MothMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); + registry.fill(HIST("h2DaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); + + // qa for energy of charged daughter greater than the mother track with mass hypothesis + float pCharDaug = std::hypot(kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()); + float pMoth = std::hypot(kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()); + float chargedDauE = std::hypot(pCharDaug, massChargedDaug); + float motherE = std::hypot(pMoth, massMoth); + if (chargedDauE < motherE) { + registry.fill(HIST("hInvMassNegNeutDaugE"), invMass); + if (isKinkSignal) { + registry.fill(HIST("hTrueSignalInvMassNegNeutDaugE"), invMass); + } + } + HypKinkCandidate hypkinkCand; fillCandidate(hypkinkCand, collision, kinkCand, motherTrack, daugTrack); hypkinkCand.nSigmaTOFDaug = nSigmaTOF; std::array posDecVtx = {kinkCand.xDecVtx() + collision.posX(), kinkCand.yDecVtx() + collision.posY(), kinkCand.zDecVtx() + collision.posZ()}; - - o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; - o2::dataformats::VertexBase secondaryVtx = {{posDecVtx[0], posDecVtx[1], posDecVtx[2]}, {covPosSV[0], covPosSV[1], covPosSV[2], covPosSV[3], covPosSV[4], covPosSV[5]}}; - std::array refitPPV = {-999.f}; - std::array refitPSV = {-999.f}; - auto motherTrackPar = getTrackParCov(motherTrack); - if (refitMotherTrack(motherTrack, motherTrackPar, primaryVtx, secondaryVtx)) { - motherTrackPar.getPxPyPzGlo(refitPSV); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - motherTrackPar.getPxPyPzGlo(refitPPV); - } + float recSVR = std::hypot(posDecVtx[0], posDecVtx[1]); // QA, store mcInfo for true signals if (isKinkSignal) { auto mcMothTrack = motherTrack.mcParticle_as(); auto mcDaugTrack = daugTrack.mcParticle_as(); auto mcNeutTrack = particlesMC.rawIteratorAt(dauIDList[1]); - float recSVR = std::sqrt(posDecVtx[0] * posDecVtx[0] + posDecVtx[1] * posDecVtx[1]); - registry.fill(HIST("hDiffSVx"), posDecVtx[0] - mcDaugTrack.vx()); - registry.fill(HIST("hDiffSVy"), posDecVtx[1] - mcDaugTrack.vy()); - registry.fill(HIST("hDiffSVz"), posDecVtx[2] - mcDaugTrack.vz()); - registry.fill(HIST("h2RecSVRVsTrueSVR"), recSVR, std::hypot(mcDaugTrack.vx(), mcDaugTrack.vy())); - registry.fill(HIST("h2TrueMotherDiffPtVsRecSVR"), recSVR, mcMothTrack.pt() - kinkCand.ptMoth()); - registry.fill(HIST("h2TrueMotherDiffEtaVsRecSVR"), recSVR, mcMothTrack.eta() - motherTrack.eta()); - registry.fill(HIST("hDiffDauPx"), kinkCand.pxDaug() - mcDaugTrack.px()); - registry.fill(HIST("hDiffDauPy"), kinkCand.pyDaug() - mcDaugTrack.py()); - registry.fill(HIST("hDiffDauPz"), kinkCand.pzDaug() - mcDaugTrack.pz()); + float trueSVR = std::hypot(mcDaugTrack.vx(), mcDaugTrack.vy()); + registry.fill(HIST("hDeltaSVx"), posDecVtx[0] - mcDaugTrack.vx()); + registry.fill(HIST("hDeltaSVy"), posDecVtx[1] - mcDaugTrack.vy()); + registry.fill(HIST("hDeltaSVz"), posDecVtx[2] - mcDaugTrack.vz()); + registry.fill(HIST("hDeltaSVRVsTrueSVR"), trueSVR, recSVR - trueSVR); + registry.fill(HIST("h2RecSVRVsTrueSVR"), recSVR, trueSVR); + registry.fill(HIST("h2TrueMotherDeltaPtVsRecSVR"), recSVR, mcMothTrack.pt() - kinkCand.ptMoth()); + registry.fill(HIST("h2TrueMotherDeltaEtaVsRecSVR"), recSVR, mcMothTrack.eta() - motherTrack.eta()); + registry.fill(HIST("hDeltaDauPx"), kinkCand.pxDaug() - mcDaugTrack.px()); + registry.fill(HIST("hDeltaDauPy"), kinkCand.pyDaug() - mcDaugTrack.py()); + registry.fill(HIST("hDeltaDauPz"), kinkCand.pzDaug() - mcDaugTrack.pz()); registry.fill(HIST("h2TrueSignalMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); registry.fill(HIST("h2TrueDaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); @@ -859,11 +902,10 @@ struct HyperkinkRecoTask { hypkinkCand.isMatter, hypkinkCand.lastPosMoth[0], hypkinkCand.lastPosMoth[1], hypkinkCand.lastPosMoth[2], hypkinkCand.momMothSV[0], hypkinkCand.momMothSV[1], hypkinkCand.momMothSV[2], - refitPPV[0], refitPPV[1], refitPPV[2], - refitPSV[0], refitPSV[1], refitPSV[2], hypkinkCand.momDaugSV[0], hypkinkCand.momDaugSV[1], hypkinkCand.momDaugSV[2], hypkinkCand.dcaXYMothPv, hypkinkCand.dcaXYDaugPv, hypkinkCand.dcaKinkTopo, hypkinkCand.chi2ITSMoth, hypkinkCand.itsClusterSizeMoth, hypkinkCand.itsClusterSizeDaug, + hypkinkCand.tpcMomDaug, hypkinkCand.tpcSignalDaug, hypkinkCand.tpcNClsPIDDaug, hypkinkCand.nSigmaTPCDaug, hypkinkCand.nSigmaITSDaug, hypkinkCand.nSigmaTOFDaug, hypkinkCand.isSignal, hypkinkCand.isSignalReco, hypkinkCand.isCollReco, hypkinkCand.isSurvEvSelection, hypkinkCand.truePosSV[0], hypkinkCand.truePosSV[1], hypkinkCand.truePosSV[2], @@ -923,7 +965,6 @@ struct HyperkinkRecoTask { -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, true, false, isReconstructedMCCollisions[mcparticle.mcCollisionId()], isSelectedMCCollisions[mcparticle.mcCollisionId()], hypkinkCand.truePosSV[0], hypkinkCand.truePosSV[1], hypkinkCand.truePosSV[2], hypkinkCand.trueMomMothPV[0], hypkinkCand.trueMomMothPV[1], hypkinkCand.trueMomMothPV[2], @@ -996,8 +1037,8 @@ struct HyperkinkQa { const AxisSpec nsigmaAxis{nsigmaBins, "TPC n#sigma"}; const AxisSpec itsnsigmaAxis{nsigmaBins, "ITS n#sigma"}; const AxisSpec invMassAxis{invMassBins, "Inv Mass (GeV/#it{c}^{2})"}; - const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta p_{T} (GeV/#it{c})"}; - const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta p_{z} (GeV/#it{c})"}; + const AxisSpec deltaPtAxis{200, -10.f, 10.f, "#Delta p_{T} (GeV/#it{c})"}; + const AxisSpec deltaPzAxis{200, -10.f, 10.f, "#Delta p_{z} (GeV/#it{c})"}; const AxisSpec itsRadiusAxis{radiusBins, "ITS R (cm)"}; const AxisSpec svRadiuAxis{radiusBins, "Decay Vertex R (cm)"}; @@ -1054,9 +1095,9 @@ struct HyperkinkQa { hMothCounter->GetXaxis()->SetBinLabel(7, "ITS IR"); hMothCounter->GetXaxis()->SetBinLabel(8, "ITS chi2"); hMothCounter->GetXaxis()->SetBinLabel(9, "pt"); - recoQAHist.add("h2TrueMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); - recoQAHist.add("h2TrueMotherDiffEtaVsTrueSVR", ";Decay Vertex R (cm);#Delta #eta;", HistType::kTH2F, {svRadiuAxis, {200, -1.f, 1.f}}); - recoQAHist.add("h2GoodMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); + recoQAHist.add("h2TrueMotherDeltaPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, deltaPtAxis}); + recoQAHist.add("h2TrueMotherDeltaEtaVsTrueSVR", ";Decay Vertex R (cm);#Delta #eta;", HistType::kTH2F, {svRadiuAxis, {200, -1.f, 1.f}}); + recoQAHist.add("h2GoodMotherDeltaPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, deltaPtAxis}); hDaugCounter = recoQAHist.add("hDaugCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); hDaugTPCNSigma = recoQAHist.add("hDaugTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); @@ -1082,6 +1123,10 @@ struct HyperkinkQa { recoQAHist.add("hDaugITSNSigma", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); recoQAHist.add("hRecoDaugPVsITSNSigma", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); recoQAHist.add("hRecoCandidateCount", "", HistType::kTH1F, {{4, 0.f, 4.f}}); + + recoQAHist.add("hDiffZTracks", "", HistType::kTH1F, {{200, -100.f, 100.f}}); + recoQAHist.add("hDiffAbsZTracks", "", HistType::kTH1F, {{200, -100.f, 100.f}}); + recoQAHist.add("hDiffXTracks", "", HistType::kTH1F, {{200, -100.f, 100.f}}); } } @@ -1308,12 +1353,12 @@ struct HyperkinkQa { auto motherTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); bool isGoodMother = motherTrackCheck(motherTrack, hMothCounter); float svR = RecoDecay::sqrtSumOfSquares(svPos[0], svPos[1]); - float diffpt = mcparticle.pt() - charge * motherTrack.pt(); + float deltapt = mcparticle.pt() - charge * motherTrack.pt(); - recoQAHist.fill(HIST("h2TrueMotherDiffPtVsTrueSVR"), svR, diffpt); - recoQAHist.fill(HIST("h2TrueMotherDiffEtaVsTrueSVR"), svR, mcparticle.eta() - motherTrack.eta()); + recoQAHist.fill(HIST("h2TrueMotherDeltaPtVsTrueSVR"), svR, deltapt); + recoQAHist.fill(HIST("h2TrueMotherDeltaEtaVsTrueSVR"), svR, mcparticle.eta() - motherTrack.eta()); if (isGoodMother) { - recoQAHist.fill(HIST("h2GoodMotherDiffPtVsTrueSVR"), svR, diffpt); + recoQAHist.fill(HIST("h2GoodMotherDeltaPtVsTrueSVR"), svR, deltapt); } // if mother track and charged daughters are all reconstructed @@ -1330,6 +1375,12 @@ struct HyperkinkQa { recoQAHist.fill(HIST("hMothIsPVContributer"), motherTrack.isPVContributor() ? 1.5 : 0.5); recoQAHist.fill(HIST("hDaugIsPVContributer"), daughterTrack.isPVContributor() ? 1.5 : 0.5); + if (svR > LayerRadii[3]) { + recoQAHist.fill(HIST("hDiffZTracks"), daughterTrack.z() - motherTrack.z()); + recoQAHist.fill(HIST("hDiffAbsZTracks"), std::abs(daughterTrack.z()) - std::abs(motherTrack.z())); + recoQAHist.fill(HIST("hDiffXTracks"), daughterTrack.x() - motherTrack.x()); + } + float itsNSigma = getITSNSigma(daughterTrack, itsResponse, pidTypeDaug); if (daughterTrack.hasITS()) { recoQAHist.fill(HIST("hDaugITSNSigma"), daughterTrack.sign() * daughterTrack.p(), itsNSigma); diff --git a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx index e164dc2794c..51693e178b1 100644 --- a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx +++ b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx @@ -182,7 +182,8 @@ struct reduced3bodyCreator { // In case override, don't proceed, please - no CCDB access required auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPMagField* grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); + ccdb->clearCache(grpmagPath); + o2::parameters::GRPMagField* grpmag = ccdb->getSpecific(grpmagPath, run3grp_timestamp); if (!grpmag) { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; } diff --git a/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx b/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx index 842c0e46c82..0f1ea4cdbe7 100644 --- a/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx +++ b/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx @@ -751,10 +751,17 @@ struct f1protonreducedtable { continue; // check if the pair is unlike or wrongsign - auto pairsign = 1; + auto pairsign = 100; if (PionCharge.at(i1) * KaonCharge.at(i2) > 0) { qaRegistry.fill(HIST("hInvMassf1Like"), F1Vector.M(), F1Vector.Pt()); pairsign = -1; + } else if (PionCharge.at(i1) * KaonCharge.at(i2) < 0) { + if (KaonCharge.at(i2) > 0) { + pairsign = 1; + } + if (KaonCharge.at(i2) < 0) { + pairsign = 2; + } } ROOT::Math::PtEtaPhiMVector temp(F1Vector.Pt(), F1Vector.Eta(), F1Vector.Phi(), F1Vector.M()); f1resonance.push_back(temp); diff --git a/PWGLF/TableProducer/Strangeness/cascadeflow.cxx b/PWGLF/TableProducer/Strangeness/cascadeflow.cxx index dc38426e90e..9974831a520 100644 --- a/PWGLF/TableProducer/Strangeness/cascadeflow.cxx +++ b/PWGLF/TableProducer/Strangeness/cascadeflow.cxx @@ -174,6 +174,7 @@ struct cascadeFlow { Configurable cfgShiftCorr{"cfgShiftCorr", 0, ""}; Configurable cfgShiftPath{"cfgShiftPath", "Users/j/junlee/Qvector/QvecCalib/Shift", "Path for Shift"}; Configurable cfgnMods{"cfgnMods", 1, "The number of modulations of interest starting from 2"}; + // Configurable cfgHarmonic{"cfgHarmonic", 2, "Harmonic for event plane calculation"}; // THN axes ConfigurableAxis thnConfigAxisFT0C{"thnConfigAxisFT0C", {8, 0, 80}, "FT0C centrality (%)"}; @@ -703,6 +704,8 @@ struct cascadeFlow { float maxMass[2]{1.36, 1.73}; float minMassLambda[2]{1.09, 1.09}; float maxMassLambda[2]{1.14, 1.14}; + const AxisSpec shiftAxis = {10, 0, 10, "shift"}; + const AxisSpec basisAxis = {2, 0, 2, "basis"}; const AxisSpec massCascAxis[2]{{static_cast((maxMass[0] - minMass[0]) / 0.001f), minMass[0], maxMass[0], "#Xi candidate mass (GeV/c^{2})"}, {static_cast((maxMass[1] - minMass[1]) / 0.001f), minMass[1], maxMass[1], "#Omega candidate mass (GeV/c^{2})"}}; const AxisSpec massLambdaAxis[2]{{static_cast((maxMassLambda[0] - minMassLambda[0]) / 0.001f), minMassLambda[0], maxMassLambda[0], "#Lambda candidate mass (GeV/c^{2})"}, @@ -726,6 +729,10 @@ struct cascadeFlow { resolution.add("QVectorsT0CTPCC_Shifted", "QVectorsT0CTPCC_Shifted", HistType::kTH2F, {axisQVs, CentAxis}); resolution.add("QVectorsTPCAC_Shifted", "QVectorsTPCAC_Shifted", HistType::kTH2F, {axisQVs, CentAxis}); + histos.add("ShiftFT0C", "ShiftFT0C", kTProfile3D, {CentAxis, basisAxis, shiftAxis}); + histos.add("ShiftTPCL", "ShiftTPCL", kTProfile3D, {CentAxis, basisAxis, shiftAxis}); + histos.add("ShiftTPCR", "ShiftTPCR", kTProfile3D, {CentAxis, basisAxis, shiftAxis}); + histos.add("hNEvents", "hNEvents", {HistType::kTH1F, {{10, 0.f, 10.f}}}); for (Int_t n = 1; n <= histos.get(HIST("hNEvents"))->GetNbinsX(); n++) { histos.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(n, hNEventsLabels[n - 1]); @@ -1041,6 +1048,17 @@ struct cascadeFlow { const float psiTPCC = std::atan2(coll.qvecBNegIm(), coll.qvecBNegRe()) * 0.5f; float psiT0CCorr = psiT0C; + for (int ishift = 1; ishift <= 10; ishift++) { + histos.fill(HIST("ShiftFT0C"), coll.centFT0C(), 0.5, ishift - 0.5, std::sin(ishift * 2 * psiT0C)); + histos.fill(HIST("ShiftFT0C"), coll.centFT0C(), 1.5, ishift - 0.5, std::cos(ishift * 2 * psiT0C)); + + histos.fill(HIST("ShiftTPCL"), coll.centFT0C(), 0.5, ishift - 0.5, std::sin(ishift * 2 * psiTPCA)); + histos.fill(HIST("ShiftTPCL"), coll.centFT0C(), 1.5, ishift - 0.5, std::cos(ishift * 2 * psiTPCA)); + + histos.fill(HIST("ShiftTPCR"), coll.centFT0C(), 0.5, ishift - 0.5, std::sin(ishift * 2 * psiTPCC)); + histos.fill(HIST("ShiftTPCR"), coll.centFT0C(), 1.5, ishift - 0.5, std::cos(ishift * 2 * psiTPCC)); + } + if (cfgShiftCorr) { currentRunNumber = coll.runNumber(); if (currentRunNumber != lastRunNumber) { diff --git a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx index 32ed292dddd..511dc283ce3 100644 --- a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx +++ b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx @@ -20,61 +20,74 @@ // gianni.shigeru.setoue.liveraro@cern.ch // -#include -#include -#include -#include +#include "PWGLF/DataModel/LFSigmaTables.h" +#include "PWGLF/DataModel/LFStrangenessMLTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/ASoA.h" -#include "ReconstructionDataFormats/Track.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" #include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "Common/CCDB/ctpRateFetcher.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGLF/DataModel/LFStrangenessMLTables.h" -#include "PWGLF/DataModel/LFSigmaTables.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "Math/Vector3D.h" +#include +#include #include #include -#include #include #include -#include +#include + +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; using dauTracks = soa::Join; -using V0DerivedMCDatas = soa::Join; -using V0StandardDerivedDatas = soa::Join; +using V0StandardDerivedDatas = soa::Join; +using V0DerivedMCDatas = soa::Join; +using V0TOFStandardDerivedDatas = soa::Join; +using V0TOFDerivedMCDatas = soa::Join; struct sigma0builder { Service ccdb; ctpRateFetcher rateFetcher; - // SliceCache cache; - - Produces sigma0cores; // save sigma0 candidates for analysis - Produces sigmaPhotonExtras; // save sigma0 candidates for analysis - Produces sigmaLambdaExtras; // save sigma0 candidates for analysis - Produces sigma0mccores; - - // For manual sliceBy - // PresliceUnsorted perCollisionMCDerived = o2::aod::v0data::straCollisionId; - // PresliceUnsorted perCollisionSTDDerived = o2::aod::v0data::straCollisionId; - PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; - + //__________________________________________________ + // Sigma0 specific + Produces sigma0cores; // sigma0 candidates info for analysis + Produces sigmaPhotonExtras; // photons from sigma0 candidates info + Produces sigmaLambdaExtras; // lambdas from sigma0 candidates info + Produces sigma0CollRefs; // references collisions from Sigma0Cores + Produces sigma0mccores; // Reco sigma0 MC properties + Produces sigma0Gens; // Generated sigma0s + Produces sigma0GenCollRefs; // references collisions from sigma0Gens + + //__________________________________________________ + // Pi0 specific + Produces pi0cores; // pi0 candidates info for analysis + Produces pi0coresRefs; // references collisions from photonpair + Produces pi0coresmc; // Reco pi0 MC properties + Produces pi0Gens; // Generated pi0s + Produces pi0GenCollRefs; // references collisions from pi0Gens + + //__________________________________________________ // pack track quality but separte also afterburner // dynamic range: 0-31 enum selection : int { hasTPC = 0, @@ -86,48 +99,16 @@ struct sigma0builder { // Histogram registry HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable fillQAhistos{"fillQAhistos", false, "if true, fill QA histograms"}; - Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study"}; - Configurable doPi0QA{"doPi0QA", true, "Flag to fill QA histos for pi0 rejection study."}; Configurable doAssocStudy{"doAssocStudy", false, "Do v0 to collision association study."}; - - // Event level Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; + Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; Configurable fIRCrashOnNull{"fIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; - struct : ConfigurableGroup { - Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; - Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; - Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; - Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; - Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; - Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; - Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; - Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; - Configurable rejectSameBunchPileup{"rejectSameBunchPileup", false, "reject collisions in case of pileup with another collision in the same foundBC"}; - Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds"}; - Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; - Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds"}; - Configurable requireNoCollInTimeRangeVzDep{"requireNoCollInTimeRangeVzDep", false, "reject collisions corrupted by the cannibalism, with other collisions with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ"}; - Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; - Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; - Configurable requireINEL0{"requireINEL0", false, "require INEL>0 event selection"}; - Configurable requireINEL1{"requireINEL1", false, "require INEL>1 event selection"}; - Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; - Configurable useEvtSelInDenomEff{"useEvtSelInDenomEff", false, "Consider event selections in the recoed <-> gen collision association for the denominator (or numerator) of the acc. x eff. (or signal loss)?"}; - Configurable applyZVtxSelOnMCPV{"applyZVtxSelOnMCPV", false, "Apply Z-vtx cut on the PV of the generated collision?"}; - Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; - // fast check on occupancy - Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; - Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; - - // fast check on interaction rate - Configurable minIR{"minIR", -1, "minimum IR collisions"}; - Configurable maxIR{"maxIR", -1, "maximum IR collisions"}; - - } eventSelections; + // Tables to fill + Configurable fillPi0Tables{"fillPi0Tables", false, "fill pi0 tables for QA"}; + Configurable fillSigma0Tables{"fillSigma0Tables", true, "fill sigma0 tables for analysis"}; // For ML Selection Configurable useMLScores{"useMLScores", false, "use ML scores to select candidates"}; @@ -137,7 +118,7 @@ struct sigma0builder { // For standard approach: //// Lambda criteria: - Configurable V0Rapidity{"V0Rapidity", 0.8, "v0 rapidity"}; + Configurable V0Rapidity{"V0Rapidity", 0.5, "v0 rapidity"}; Configurable LambdaDauPseudoRap{"LambdaDauPseudoRap", 1.5, "Max pseudorapidity of daughter tracks"}; Configurable LambdaMinDCANegToPv{"LambdaMinDCANegToPv", 0.0, "min DCA Neg To PV (cm)"}; @@ -147,7 +128,7 @@ struct sigma0builder { Configurable LambdaMaxv0radius{"LambdaMaxv0radius", 60, "Max V0 radius (cm)"}; Configurable LambdaWindow{"LambdaWindow", 0.05, "Mass window around expected (in GeV/c2)"}; - //// Photon criteria: + //// Photon criteria (for sigma0s and pi0s): Configurable PhotonMaxDauPseudoRap{"PhotonMaxDauPseudoRap", 1.5, "Max pseudorapidity of daughter tracks"}; Configurable PhotonMinDCAToPv{"PhotonMinDCAToPv", 0.0, "Min DCA daughter To PV (cm)"}; Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; @@ -159,18 +140,18 @@ struct sigma0builder { Configurable Sigma0Window{"Sigma0Window", 0.1, "Mass window around expected (in GeV/c2)"}; Configurable SigmaMaxRap{"SigmaMaxRap", 0.8, "Max sigma0 rapidity"}; - //// Extras: - Configurable Pi0PhotonMinDCADauToPv{"Pi0PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; - Configurable Pi0PhotonMaxDCAV0Dau{"Pi0PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; - Configurable Pi0PhotonMinTPCCrossedRows{"Pi0PhotonMinTPCCrossedRows", 0, "Min daughter TPC Crossed Rows"}; - Configurable Pi0PhotonMaxTPCNSigmas{"Pi0PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; - Configurable Pi0PhotonMaxEta{"Pi0PhotonMaxEta", 0.8, "Max photon rapidity"}; - Configurable Pi0PhotonMinRadius{"Pi0PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; - Configurable Pi0PhotonMaxRadius{"Pi0PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; - Configurable Pi0PhotonMaxQt{"Pi0PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; - Configurable Pi0PhotonMaxAlpha{"Pi0PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; - Configurable Pi0PhotonMinV0cospa{"Pi0PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; - Configurable Pi0PhotonMaxMass{"Pi0PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; + //// Pi0 criteria:: + Configurable Pi0MaxRap{"Pi0MaxRap", 0.8, "Max Pi0 Rapidity"}; + Configurable Pi0MassWindow{"Pi0MassWindow", 0.115, "Mass window around expected (in GeV/c2)"}; + + //// Generated particles criteria: + struct : ConfigurableGroup { + Configurable doQA{"doQA", true, "If True, fill QA histos"}; + Configurable mc_keepOnlyFromGenerator{"mc_keepOnlyFromGenerator", false, "Keep only mcparticles from the generator"}; + Configurable mc_keepOnlyFromTransport{"mc_keepOnlyFromTransport", false, "Keep only mcparticles from the transport code"}; + Configurable mc_selectMCProcess{"mc_selectMCProcess", -1, "Keep only mcparticles produced in the selected MC process"}; + Configurable mc_rapidityWindow{"mc_rapidityWindow", 0.5, "Max generated particle rapidity"}; + } genSelections; // Axis // base properties @@ -181,16 +162,8 @@ struct sigma0builder { ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.05f, 1.151f}, "M_{#Lambda} (GeV/c^{2})"}; ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, -0.1f, 0.5f}, "M_{#Gamma}"}; - ConfigurableAxis axisPi0Mass{"axisPi0Mass", {200, 0.08f, 0.18f}, "M_{#Pi^{0}}"}; ConfigurableAxis axisK0SMass{"axisK0SMass", {200, 0.4f, 0.6f}, "M_{K^{0}}"}; - // AP plot axes - ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; - ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; - - // Track quality axes - ConfigurableAxis axisTPCrows{"axisTPCrows", {160, 0.0f, 160.0f}, "N TPC rows"}; - // topological variable QA axes ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; ConfigurableAxis axisXY{"axisXY", {120, -120.0f, 120.0f}, "XY axis"}; @@ -199,47 +172,30 @@ struct sigma0builder { ConfigurableAxis axisPA{"axisPA", {100, 0.0f, 1}, "Pointing angle"}; ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; ConfigurableAxis axisCandSel{"axisCandSel", {7, 0.5f, +7.5f}, "Candidate Selection"}; - ConfigurableAxis axisNch{"axisNch", {300, 0.0f, 3000.0f}, "N_{ch}"}; - ConfigurableAxis axisIRBinning{"axisIRBinning", {150, 0, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisIRBinning{"axisIRBinning", {151, -10, 1500}, "Binning for the interaction rate (kHz)"}; - int nSigmaCandidates = 0; void init(InitContext const&) { + LOGF(info, "Initializing now: cross-checking correctness..."); + if (doprocessRealData + + doprocessRealDataWithTOF + + doprocessMonteCarlo + + doprocessMonteCarloWithTOF > + 1) { + LOGF(fatal, "You have enabled more than one process function. Please check your configuration! Aborting now."); + } + // setting CCDB service ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setFatalWhenNull(false); - // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1D, {{21, -0.5f, +20.5f}}); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); - if (doPPAnalysis) { - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "INEL>0"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "INEL>1"); - } else { - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); - } - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(19, "Below min IR"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(20, "Above max IR"); - histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + histos.add("PhotonSel/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, axisK0SMass}); + histos.add("PhotonSel/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); + histos.add("PhotonSel/h2dV0XY", "h2dV0XY", kTH2F, {axisXY, axisXY}); + histos.add("PhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Photon Mass Cut"); @@ -258,6 +214,8 @@ struct sigma0builder { histos.add("PhotonSel/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); histos.add("PhotonSel/h3dPhotonMass", "h3dPhotonMass", kTH3D, {axisCentrality, axisPt, axisPhotonMass}); + histos.add("LambdaSel/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, axisK0SMass}); + histos.add("LambdaSel/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisLambdaMass, axisPhotonMass}); histos.add("LambdaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Lambda Mass Cut"); @@ -284,32 +242,9 @@ struct sigma0builder { histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Sigma Y Window"); // For selection: - histos.add("SigmaSel/h3dMassSigma0BeforeSel", "h3dMassSigma0BeforeSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("SigmaSel/hSigmaMass", "hSigmaMass", kTH1F, {axisSigmaMass}); - histos.add("SigmaSel/hSigmaMassWindow", "hSigmaMassWindow", kTH1F, {{200, -0.09f, 0.11f}}); - histos.add("SigmaSel/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); histos.add("SigmaSel/hSigmaMassSelected", "hSigmaMassSelected", kTH1F, {axisSigmaMass}); - histos.add("SigmaSel/h3dMassSigma0AfterSel", "h3dMassSigma0AfterSel", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); - - if (fillQAhistos) { - histos.add("GeneralQA/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add("GeneralQA/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisLambdaMass, axisPhotonMass}); - histos.add("GeneralQA/h3dMassSigma0VsDaupTs", "h3dMassSigma0VsDaupTs", kTH3F, {axisPt, axisPt, axisSigmaMass}); - histos.add("GeneralQA/h2dMassGammaVsK0SAfterMassSel", "h2dMassGammaVsK0SAfterMassSel", kTH2D, {axisPhotonMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassLambdaVsK0SAfterMassSel", "h2dMassLambdaVsK0SAfterMassSel", kTH2D, {axisLambdaMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassGammaVsLambdaAfterMassSel", "h2dMassGammaVsLambdaAfterMassSel", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add("GeneralQA/h2dV0XY", "h2dV0XY", kTH2F, {axisXY, axisXY}); - } - if (fGetIR) { - histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); - histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1F, {axisIRBinning}); - histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2F, {axisCentrality, axisIRBinning}); - } - - if (doAssocStudy && doprocessMonteCarlo) { + if (doAssocStudy && (doprocessMonteCarlo || doprocessMonteCarloWithTOF)) { histos.add("V0AssoQA/h2dIRVsPt_TrueGamma", "h2dIRVsPt_TrueGamma", kTH2F, {axisIRBinning, axisPt}); histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma", "h3dPAVsIRVsPt_TrueGamma", kTH3F, {axisPA, axisIRBinning, axisPt}); histos.add("V0AssoQA/h2dIRVsPt_TrueGamma_BadCollAssig", "h2dIRVsPt_TrueGamma_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); @@ -322,225 +257,236 @@ struct sigma0builder { } // MC - if (doprocessMonteCarlo) { - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocGamma", "h2dPtVsCentralityBeforeSel_MCAssocGamma", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocLambda", "h2dPtVsCentralityBeforeSel_MCAssocLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocALambda", "h2dPtVsCentralityBeforeSel_MCAssocALambda", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocSigma0", "h2dPtVsCentralityBeforeSel_MCAssocSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocASigma0", "h2dPtVsCentralityBeforeSel_MCAssocASigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc", "h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc", kTH2D, {axisPt, axisPt}); - histos.add("MC/h2dSigma0PtVsGammaPtBeforeSel_MCAssoc", "h2dSigma0PtVsGammaPtBeforeSel_MCAssoc", kTH2D, {axisPt, axisPt}); - histos.add("MC/h2dPtVsCentralityAfterSel_MCAssocSigma0", "h2dPtVsCentralityAfterSel_MCAssocSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityAfterSel_MCAssocASigma0", "h2dPtVsCentralityAfterSel_MCAssocASigma0", kTH2D, {axisCentrality, axisPt}); + if (doprocessMonteCarlo || doprocessMonteCarloWithTOF) { histos.add("MC/h2dGammaXYConversion", "h2dGammaXYConversion", kTH2F, {axisXY, axisXY}); + histos.add("MC/h2dPtVsCentrality_MCAssocGamma", "h2dPtVsCentrality_MCAssocGamma", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_MCAssocLambda", "h2dPtVsCentrality_MCAssocLambda", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_MCAssocALambda", "h2dPtVsCentrality_MCAssocALambda", kTH2D, {axisCentrality, axisPt}); } - // For background decomposition - if (fillBkgQAhistos && doprocessMonteCarlo) { - histos.add("BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("BkgStudy/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("BkgStudy/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("BkgStudy/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - } + if (doprocessGeneratedRun3 && genSelections.doQA) { - // For Pi0 QA - if (doPi0QA) { - histos.add("Pi0QA/h3dMassPi0BeforeSel_MCAssoc", "h3dMassPi0BeforeSel_MCAssoc", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - histos.add("Pi0QA/h3dMassPi0AfterSel_MCAssoc", "h3dMassPi0AfterSel_MCAssoc", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - histos.add("Pi0QA/h3dMassPi0BeforeSel_Candidates", "h3dMassPi0BeforeSel_Candidates", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - histos.add("Pi0QA/h3dMassPi0AfterSel_Candidates", "h3dMassPi0AfterSel_Candidates", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - } + // Pi0s + histos.add("GenQA/hGenPi0", "hGenPi0", kTH1D, {axisPt}); + + auto hPrimaryPi0s = histos.add("GenQA/hPrimaryPi0s", "hPrimaryPi0s", kTH1D, {{2, -0.5f, 1.5f}}); + hPrimaryPi0s->GetXaxis()->SetBinLabel(1, "All Pi0s"); + hPrimaryPi0s->GetXaxis()->SetBinLabel(2, "Primary Pi0s"); + + histos.add("GenQA/h2dPi0MCSourceVsPDGMother", "h2dPi0MCSourceVsPDGMother", kTHnSparseD, {{2, -0.5f, 1.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("GenQA/h2dPi0NDaughtersVsPDG", "h2dPi0NDaughtersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); + + auto h2DGenPi0TypeVsProducedByGen = histos.add("GenQA/h2DGenPi0TypeVsProducedByGen", "h2DGenPi0TypeVsProducedByGen", kTH2D, {{2, -0.5f, 1.5f}, {2, -0.5f, 1.5f}}); + h2DGenPi0TypeVsProducedByGen->GetXaxis()->SetBinLabel(1, "Sterile"); + h2DGenPi0TypeVsProducedByGen->GetXaxis()->SetBinLabel(2, "Non-Sterile"); + h2DGenPi0TypeVsProducedByGen->GetYaxis()->SetBinLabel(1, "Generator"); + h2DGenPi0TypeVsProducedByGen->GetYaxis()->SetBinLabel(2, "Transport"); + + // ______________________________________________________ + // Sigma0s + histos.add("GenQA/hGenSigma0", "hGenSigma0", kTH1D, {axisPt}); + histos.add("GenQA/hGenAntiSigma0", "hGenAntiSigma0", kTH1D, {axisPt}); + + histos.add("GenQA/h2dGenSigma0xy_Generator", "hGenSigma0xy_Generator", kTH2D, {axisXY, axisXY}); + histos.add("GenQA/h2dGenSigma0xy_Transport", "hGenSigma0xy_Transport", kTH2D, {axisXY, axisXY}); + histos.add("GenQA/hGenSigma0Radius_Generator", "hGenSigma0Radius_Generator", kTH1D, {axisRadius}); + histos.add("GenQA/hGenSigma0Radius_Transport", "hGenSigma0Radius_Transport", kTH1D, {axisRadius}); + + histos.add("GenQA/h2dSigma0MCSourceVsPDGMother", "h2dSigma0MCSourceVsPDGMother", kTHnSparseD, {{2, -0.5f, 1.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("GenQA/h2dSigma0NDaughtersVsPDG", "h2dSigma0NDaughtersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); + + auto hPrimarySigma0s = histos.add("GenQA/hPrimarySigma0s", "hPrimarySigma0s", kTH1D, {{2, -0.5f, 1.5f}}); + hPrimarySigma0s->GetXaxis()->SetBinLabel(1, "All Sigma0s"); + hPrimarySigma0s->GetXaxis()->SetBinLabel(2, "Primary Sigma0s"); + + auto hGenSpecies = histos.add("GenQA/hGenSpecies", "hGenSpecies", kTH1D, {{4, -0.5f, 3.5f}}); + hGenSpecies->GetXaxis()->SetBinLabel(1, "All Prim. Lambda"); + hGenSpecies->GetXaxis()->SetBinLabel(2, "All Prim. ALambda"); + hGenSpecies->GetXaxis()->SetBinLabel(5, "All Sigma0s"); + hGenSpecies->GetXaxis()->SetBinLabel(6, "All ASigma0s"); - if (doprocessGeneratedRun3) { - - histos.add("Gen/hGenEvents", "hGenEvents", kTH2F, {{axisNch}, {2, -0.5f, +1.5f}}); - histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(1, "All gen. events"); - histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(2, "Gen. with at least 1 rec. events"); - - histos.add("Gen/hGenEventCentrality", "hGenEventCentrality", kTH1F, {{101, 0.0f, 101.0f}}); - histos.add("Gen/hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", kTH2F, {axisCentrality, {50, -0.5f, 49.5f}}); - histos.add("Gen/hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", kTH2F, {axisCentrality, {50, -0.5f, 49.5f}}); - histos.add("Gen/hCentralityVsMultMC", "hCentralityVsMultMC", kTH2F, {{101, 0.0f, 101.0f}, axisNch}); - histos.add("Gen/h2dGenGamma", "h2dGenGamma", kTH2D, {axisCentrality, axisPt}); - histos.add("Gen/h2dGenLambda", "h2dGenLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("Gen/h2dGenAntiLambda", "h2dGenAntiLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("Gen/h2dGenGammaVsMultMC_RecoedEvt", "h2dGenGammaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenLambdaVsMultMC_RecoedEvt", "h2dGenLambdaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenAntiLambdaVsMultMC_RecoedEvt", "h2dGenAntiLambdaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenGammaVsMultMC", "h2dGenGammaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenLambdaVsMultMC", "h2dGenLambdaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenAntiLambdaVsMultMC", "h2dGenAntiLambdaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("Gen/hEventPVzMC", "hEventPVzMC", kTH1F, {{100, -20.0f, +20.0f}}); - histos.add("Gen/hCentralityVsPVzMC", "hCentralityVsPVzMC", kTH2F, {{101, 0.0f, 101.0f}, {100, -20.0f, +20.0f}}); - - auto hPrimaryV0s = histos.add("Gen/hPrimaryV0s", "hPrimaryV0s", kTH1D, {{2, -0.5f, 1.5f}}); - hPrimaryV0s->GetXaxis()->SetBinLabel(1, "All V0s"); - hPrimaryV0s->GetXaxis()->SetBinLabel(2, "Primary V0s"); + histos.add("GenQA/hSigma0NDau", "hSigma0NDau", kTH1D, {{10, -0.5f, +9.5f}}); + histos.add("GenQA/h2dSigma0NDauVsProcess", "h2dSigma0NDauVsProcess", kTH2D, {{10, -0.5f, +9.5f}, {50, -0.5f, 49.5f}}); + + auto h2DGenSigma0TypeVsProducedByGen = histos.add("GenQA/h2DGenSigma0TypeVsProducedByGen", "h2DGenSigma0TypeVsProducedByGen", kTH2D, {{2, -0.5f, 1.5f}, {2, -0.5f, 1.5f}}); + h2DGenSigma0TypeVsProducedByGen->GetXaxis()->SetBinLabel(1, "Sterile"); + h2DGenSigma0TypeVsProducedByGen->GetXaxis()->SetBinLabel(2, "Non-Sterile"); + h2DGenSigma0TypeVsProducedByGen->GetYaxis()->SetBinLabel(1, "Generator"); + h2DGenSigma0TypeVsProducedByGen->GetYaxis()->SetBinLabel(2, "Transport"); } } - template - bool IsEventAccepted(TCollision const& collision, bool fillHists) - // check whether the collision passes our collision selections + // ______________________________________________________ + // Struct to store V0Pair properties + struct V0PairTopoInfo { + float X = -999.f; + float Y = -999.f; + float Z = -999.f; + float DCADau = -999.f; + float CosPA = -1.f; + }; + + // ______________________________________________________ + // Struct to store V0Pair MC properties + struct V0PairMCInfo { + bool fIsV01CorrectlyAssign = false; + bool fIsV02CorrectlyAssign = false; + bool fIsV01Primary = false; + bool fIsV02Primary = false; + bool fV0PairProducedByGenerator = false; + int V01PDGCode = 0; + int V02PDGCode = 0; + int V01PDGCodeMother = 0; + int V02PDGCodeMother = 0; + int V0PairPDGCode = 0; + int V0PairPDGCodeMother = 0; + int V0PairMCProcess = -1; + int V0PairMCParticleID = -1; + float V01MCpx = -999.f; + float V01MCpy = -999.f; + float V01MCpz = -999.f; + float V02MCpx = -999.f; + float V02MCpy = -999.f; + float V02MCpz = -999.f; + float V0PairMCRadius = -999.f; + }; + + // ______________________________________________________ + // Struct to store V0Pair Generated properties + struct V0PairGenInfo { + bool IsPrimary = false; + bool IsV0Lambda = false; + bool IsV0AntiLambda = false; + bool IsPi0 = false; + bool IsSigma0 = false; + bool IsAntiSigma0 = false; + bool IsProducedByGenerator = false; + bool IsSterile = false; + int MCProcess = -1; + int MCCollId = -1; + int PDGCodeMother = 0; + int NDaughters = -1; + float MCPt = -999.f; + float MCvx = 999.f; + float MCvy = 999.f; + }; + + template + V0PairTopoInfo propagateV0PairToDCA(TV01 const& v01, TV02 const& v02) { - if (fillHists) - histos.fill(HIST("hEventSelection"), 0. /* all collisions */); - if (eventSelections.requireSel8 && !collision.sel8()) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); - if (eventSelections.requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); - if (eventSelections.rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); - if (eventSelections.rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); - if (std::abs(collision.posZ()) > eventSelections.maxZVtxPosition) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); - if (eventSelections.requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); - if (eventSelections.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); - if (eventSelections.requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); - if (eventSelections.requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); - if (eventSelections.rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); - if (eventSelections.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); - if (eventSelections.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); - if (eventSelections.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); - if (eventSelections.requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); - if (eventSelections.requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && collision.multNTracksPVeta1() < 1) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 16 /* INEL > 0 */); - if (eventSelections.requireINEL1 && collision.multNTracksPVeta1() < 2) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 17 /* INEL > 1 */); - } else { // we are in Pb-Pb - float collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); - if (eventSelections.minOccupancy >= 0 && collisionOccupancy < eventSelections.minOccupancy) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); - if (eventSelections.maxOccupancy >= 0 && collisionOccupancy > eventSelections.maxOccupancy) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); - } - // Fetch interaction rate only if required (in order to limit ccdb calls) - double interactionRate = (eventSelections.minIR >= 0 || eventSelections.maxIR >= 0) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; - if (eventSelections.minIR >= 0 && interactionRate < eventSelections.minIR) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 18 /* Below min IR */); + V0PairTopoInfo info; - if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { - return false; + // Positions + ROOT::Math::XYZVector v01position(v01.x(), v01.y(), v01.z()); + ROOT::Math::XYZVector v02position(v02.x(), v02.y(), v02.z()); + + // Momenta + ROOT::Math::XYZVector v01momentum(v01.px(), v01.py(), v01.pz()); + ROOT::Math::XYZVector v02momentum(v02.px(), v02.py(), v02.pz()); + + // Momenta (normalized) + ROOT::Math::XYZVector v01momentumNorm(v01.px() / v01.p(), v01.py() / v01.p(), v01.pz() / v01.p()); + ROOT::Math::XYZVector v02momentumNorm(v02.px() / v02.p(), v02.py() / v02.p(), v02.pz() / v02.p()); + + // DCADau calculation (using full momenta for precision) + ROOT::Math::XYZVector posdiff = v02position - v01position; + ROOT::Math::XYZVector cross = v01momentum.Cross(v02momentum); + + float d = 1.0f - TMath::Power(v01momentumNorm.Dot(v02momentumNorm), 2); + float t = posdiff.Dot(v01momentumNorm - v01momentumNorm.Dot(v02momentumNorm) * v02momentumNorm) / d; + float s = -posdiff.Dot(v02momentumNorm - v01momentumNorm.Dot(v02momentumNorm) * v01momentumNorm) / d; + + ROOT::Math::XYZVector pointOn1 = v01position + t * v01momentumNorm; + ROOT::Math::XYZVector pointOn2 = v02position + s * v02momentumNorm; + ROOT::Math::XYZVector PCA = 0.5 * (pointOn1 + pointOn2); + + // Calculate properties and fill struct + info.DCADau = (cross.Mag2() > 0) ? std::abs(posdiff.Dot(cross)) / cross.R() : 999.f; + info.CosPA = v01momentumNorm.Dot(v02momentumNorm); + + if (d < 1e-5f) { // Parallel or nearly parallel lines + info.X = info.Y = info.Z = 0.f; // should we use another dummy value? Perhaps 999.f? + return info; } - if (fillHists) - histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); - histos.fill(HIST("hEventCentrality"), centrality); - return true; + info.X = PCA.X(); + info.Y = PCA.Y(); + info.Z = PCA.Z(); + + return info; } - void runBkgAnalysis(bool fIsSigma, bool fIsAntiSigma, int PhotonPDGCode, int PhotonPDGCodeMother, int LambdaPDGCode, int LambdaPDGCodeMother, float sigmapT, float sigmaMass) + template + V0PairMCInfo getV0PairMCInfo(TV01 const& v01, TV02 const& v02, TCollision const& collision, TMCParticles const& mcparticles) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_All"), sigmapT, sigmaMass); + V0PairMCInfo MCinfo; - // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! - if ((PhotonPDGCode == 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122)) && (!fIsSigma && !fIsAntiSigma)) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_TrueDaughters"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dTrueDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); - } + if (!v01.has_v0MCCore() || !v02.has_v0MCCore()) + return MCinfo; - // Real Gamma x fake Lambda - if ((PhotonPDGCode == 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dTrueGammaFakeLambdaMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); - } + auto v01MC = v01.template v0MCCore_as>(); + auto v02MC = v02.template v0MCCore_as>(); - // Fake Gamma x Real Lambda - if ((PhotonPDGCode != 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122))) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dFakeGammaTrueLambdaMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + if (collision.has_straMCCollision()) { + auto MCCollision = collision.template straMCCollision_as>(); + MCinfo.fIsV01CorrectlyAssign = (v01MC.straMCCollisionId() == MCCollision.globalIndex()); + MCinfo.fIsV02CorrectlyAssign = (v02MC.straMCCollisionId() == MCCollision.globalIndex()); } - // Fake Gamma x Fake Lambda - if ((PhotonPDGCode != 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_FakeDaughters"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dFakeDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + MCinfo.V01MCpx = v01MC.pxMC(); + MCinfo.V01MCpy = v01MC.pyMC(); + MCinfo.V01MCpz = v01MC.pzMC(); + MCinfo.V02MCpx = v02MC.pxMC(); + MCinfo.V02MCpy = v02MC.pyMC(); + MCinfo.V02MCpz = v02MC.pzMC(); + + // Get corresponding entries in MCParticles table + auto MCParticle_v01 = mcparticles.rawIteratorAt(v01MC.particleIdMC()); + auto MCParticle_v02 = mcparticles.rawIteratorAt(v02MC.particleIdMC()); + + // Get MC Mothers + auto const& MCMothersList_v01 = MCParticle_v01.template mothers_as(); + auto const& MCMothersList_v02 = MCParticle_v02.template mothers_as(); + + if (!MCMothersList_v01.empty() && !MCMothersList_v02.empty()) { // Are there mothers? + + auto const& MCMother_v01 = MCMothersList_v01.front(); // First mother + auto const& MCMother_v02 = MCMothersList_v02.front(); // First mother + + if (MCMother_v01.globalIndex() == MCMother_v02.globalIndex()) { // Is it the same mother? + + MCinfo.fV0PairProducedByGenerator = MCMother_v01.producedByGenerator(); + MCinfo.V0PairPDGCode = MCMother_v01.pdgCode(); + MCinfo.V0PairMCProcess = MCMother_v01.getProcess(); + MCinfo.V0PairMCParticleID = MCMother_v01.globalIndex(); + MCinfo.V0PairMCRadius = std::hypot(MCMother_v01.vx(), MCMother_v01.vy()); // production position radius + + auto const& v0pairmothers = MCMother_v01.template mothers_as(); // Get mothers + if (!v0pairmothers.empty()) { + auto& v0PairMother = v0pairmothers.front(); // V0Pair mother, V0s grandmother + MCinfo.V0PairPDGCodeMother = v0PairMother.pdgCode(); + } + } } + + MCinfo.fIsV01Primary = v01MC.isPhysicalPrimary(); + MCinfo.fIsV02Primary = v02MC.isPhysicalPrimary(); + MCinfo.V01PDGCode = v01MC.pdgCode(); + MCinfo.V02PDGCode = v02MC.pdgCode(); + MCinfo.V01PDGCodeMother = v01MC.pdgCodeMother(); + MCinfo.V02PDGCodeMother = v02MC.pdgCodeMother(); + + return MCinfo; } + // ______________________________________________________ + // MC-specific + // Analyze v0-to-collision association template - void analyzeV0CollAssoc(TCollision const& collision, TV0Object const& fullv0s, std::vector selV0Indices, float IR, bool isPhotonAnalysis) + void analyzeV0CollAssoc(TCollision const& collision, TV0Object const& fullv0s, std::vector selV0Indices, bool isPhotonAnalysis) { auto v0MCCollision = collision.template straMCCollision_as>(); + float IR = (fGetIR) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; for (size_t i = 0; i < selV0Indices.size(); ++i) { auto v0 = fullv0s.rawIteratorAt(selV0Indices[i]); @@ -572,277 +518,179 @@ struct sigma0builder { } } - // ______________________________________________________ - // Simulated processing - // Return the list of indices to the recoed collision associated to a given MC collision. - template - std::vector getListOfRecoCollIndices(TMCollisions const& mcCollisions, TCollisions const& collisions) + template + V0PairGenInfo getV0PairGenInfo(TMCParticle const& mcParticle) { - std::vector listBestCollisionIdx(mcCollisions.size()); - for (auto const& mcCollision : mcCollisions) { - auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); - int biggestNContribs = -1; - int bestCollisionIndex = -1; - for (auto const& collision : groupedCollisions) { - // consider event selections in the recoed <-> gen collision association, for the denominator (or numerator) of the efficiency (or signal loss)? - if (eventSelections.useEvtSelInDenomEff) { - if (!IsEventAccepted(collision, false)) { - continue; - } - } - // Find the collision with the biggest nbr of PV contributors - // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 - if (biggestNContribs < collision.multPVTotalContributors()) { - biggestNContribs = collision.multPVTotalContributors(); - bestCollisionIndex = collision.globalIndex(); - } + V0PairGenInfo GenInfo; // auxiliary struct to store info + + // Fill with properties + GenInfo.IsPrimary = mcParticle.isPhysicalPrimary(); + GenInfo.IsV0Lambda = mcParticle.pdgCode() == 3122; + GenInfo.IsV0AntiLambda = mcParticle.pdgCode() == -3122; + GenInfo.IsPi0 = mcParticle.pdgCode() == 111; + GenInfo.IsSigma0 = mcParticle.pdgCode() == 3212; + GenInfo.IsAntiSigma0 = mcParticle.pdgCode() == -3212; + GenInfo.IsProducedByGenerator = mcParticle.producedByGenerator(); + GenInfo.MCProcess = mcParticle.getProcess(); + GenInfo.MCPt = mcParticle.pt(); + GenInfo.MCvx = mcParticle.vx(); // production position X + GenInfo.MCvy = mcParticle.vy(); // production position Y + + if (mcParticle.has_mcCollision()) + GenInfo.MCCollId = mcParticle.mcCollisionId(); // save this reference, please + + // Checking decay mode if sigma0 + if (GenInfo.IsSigma0 || GenInfo.IsAntiSigma0 || GenInfo.IsPi0) { + + // This is a costly operation, so we do it only for pi0s and sigma0s + auto const& daughters = mcParticle.template daughters_as(); + GenInfo.NDaughters = daughters.size(); + GenInfo.IsSterile = daughters.size() == 0; + + auto const& GenMothersList = mcParticle.template mothers_as(); + GenInfo.PDGCodeMother = (!GenMothersList.empty()) ? GenMothersList.front().pdgCode() : 0; + + if ((GenInfo.IsSigma0 || GenInfo.IsAntiSigma0) && genSelections.doQA) { + histos.fill(HIST("GenQA/h2dSigma0MCSourceVsPDGMother"), GenInfo.IsProducedByGenerator, GenInfo.PDGCodeMother); + for (auto& daughter : daughters) // checking decay modes + histos.fill(HIST("GenQA/h2dSigma0NDaughtersVsPDG"), daughters.size(), daughter.pdgCode()); + } + + if (GenInfo.IsPi0 && genSelections.doQA) { + histos.fill(HIST("GenQA/h2dPi0MCSourceVsPDGMother"), GenInfo.IsProducedByGenerator, GenInfo.PDGCodeMother); + for (auto& daughter : daughters) // checking decay modes + histos.fill(HIST("GenQA/h2dPi0NDaughtersVsPDG"), daughters.size(), daughter.pdgCode()); } - listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; } - return listBestCollisionIdx; + return GenInfo; } // ______________________________________________________ - // Simulated processing - // Fill generated event information (for event loss/splitting estimation) - template - void fillGeneratedEventProperties(TMCCollisions const& mcCollisions, TCollisions const& collisions) + // Simulated processing (subscribes to MC information too) + void fillGenQAHistos(V0PairGenInfo const& GenInfo) { - std::vector listBestCollisionIdx(mcCollisions.size()); - for (auto const& mcCollision : mcCollisions) { - // Apply selections on MC collisions - if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { - continue; + if (GenInfo.IsPi0) { + histos.fill(HIST("GenQA/hGenPi0"), GenInfo.MCPt); + histos.fill(HIST("GenQA/hPrimaryPi0s"), 0); + if (GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hPrimaryPi0s"), 1); + + if (GenInfo.IsSterile) { + if (GenInfo.IsProducedByGenerator) + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 0, 0); + else + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 0, 1); + } else { + if (GenInfo.IsProducedByGenerator) + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 1, 0); + else + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 1, 1); } - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { - continue; - } + } - if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { - continue; - } + if (GenInfo.IsV0Lambda && GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hGenSpecies"), 0); + if (GenInfo.IsV0AntiLambda && GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hGenSpecies"), 1); + + // Checking decay mode + if (GenInfo.IsSigma0 || GenInfo.IsAntiSigma0) { + histos.fill(HIST("GenQA/hSigma0NDau"), GenInfo.NDaughters); + histos.fill(HIST("GenQA/h2dSigma0NDauVsProcess"), GenInfo.NDaughters, GenInfo.MCProcess); + + const auto radius = std::hypot(GenInfo.MCvx, GenInfo.MCvy); + // Sigma0 XY and radius (separate histos for Gen/Transport) + if (GenInfo.IsProducedByGenerator) { + histos.fill(HIST("GenQA/h2dGenSigma0xy_Generator"), GenInfo.MCvx, GenInfo.MCvy); + histos.fill(HIST("GenQA/hGenSigma0Radius_Generator"), radius); + } else { + histos.fill(HIST("GenQA/h2dGenSigma0xy_Transport"), GenInfo.MCvx, GenInfo.MCvy); + histos.fill(HIST("GenQA/hGenSigma0Radius_Transport"), radius); } - histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 0 /* all gen. events*/); - - auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); - // Check if there is at least one of the reconstructed collisions associated to this MC collision - // If so, we consider it - bool atLeastOne = false; - int biggestNContribs = -1; - float centrality = 100.5f; - int nCollisions = 0; - for (auto const& collision : groupedCollisions) { - - if (!IsEventAccepted(collision, false)) { - continue; - } + // Sigma0 type vs origin (single 2D histo) + const int genIndex = GenInfo.IsProducedByGenerator ? 0 : 1; // 0 = Generator, 1 = Transport + const int typeIndex = GenInfo.IsSterile ? 0 : 1; // 0 = Sterile, 1 = Normal + histos.fill(HIST("GenQA/h2DGenSigma0TypeVsProducedByGen"), typeIndex, genIndex); - if (biggestNContribs < collision.multPVTotalContributors()) { - biggestNContribs = collision.multPVTotalContributors(); - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); - } + // Fill histograms + if (GenInfo.IsSigma0) { + histos.fill(HIST("GenQA/hGenSpecies"), 2); + histos.fill(HIST("GenQA/hGenSigma0"), GenInfo.MCPt); - nCollisions++; - atLeastOne = true; + histos.fill(HIST("GenQA/hPrimarySigma0s"), 0); + if (GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hPrimarySigma0s"), 1); } - - histos.fill(HIST("Gen/hCentralityVsNcoll_beforeEvSel"), centrality, groupedCollisions.size()); - histos.fill(HIST("Gen/hCentralityVsNcoll_afterEvSel"), centrality, nCollisions); - histos.fill(HIST("Gen/hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); - histos.fill(HIST("Gen/hCentralityVsPVzMC"), centrality, mcCollision.posZ()); - histos.fill(HIST("Gen/hEventPVzMC"), mcCollision.posZ()); - - if (atLeastOne) { - histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); - histos.fill(HIST("Gen/hGenEventCentrality"), centrality); + if (GenInfo.IsAntiSigma0) { + histos.fill(HIST("GenQA/hGenSpecies"), 3); + histos.fill(HIST("GenQA/hGenAntiSigma0"), GenInfo.MCPt); } } - return; } // ______________________________________________________ // Simulated processing (subscribes to MC information too) - template - void analyzeGeneratedV0s(TMCCollisions const& mcCollisions, TV0MCs const& V0MCCores, TCollisions const& collisions) + template + void genProcess(TMCParticles const& mcParticles) { - fillGeneratedEventProperties(mcCollisions, collisions); - std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, collisions); - for (auto const& v0MC : V0MCCores) { - if (!v0MC.has_straMCCollision()) - continue; - - histos.fill(HIST("Gen/hPrimaryV0s"), 0); - if (!v0MC.isPhysicalPrimary()) + for (auto& mcParticle : mcParticles) { + // Rapidity selection + if (TMath::Abs(mcParticle.y()) > genSelections.mc_rapidityWindow) continue; - histos.fill(HIST("Gen/hPrimaryV0s"), 1); - - // TODO: get generated sigma0s - - float ptmc = v0MC.ptMC(); - float ymc = 1e3; - if (v0MC.pdgCode() == 22) - ymc = RecoDecay::y(std::array{v0MC.pxMC(), v0MC.pyMC(), v0MC.pzMC()}, o2::constants::physics::MassGamma); - - else if (std::abs(v0MC.pdgCode()) == 3122) - ymc = v0MC.rapidityMC(1); - - if (std::abs(ymc) > V0Rapidity) - continue; - - auto mcCollision = v0MC.template straMCCollision_as>(); - if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { - continue; - } - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { - continue; - } - - if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { + // Selection on the source (generator/transport) + if (genSelections.mc_keepOnlyFromGenerator && !genSelections.mc_keepOnlyFromTransport) { + if (!mcParticle.producedByGenerator()) continue; - } } - float centrality = 100.5f; - if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { - auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); - - if (v0MC.pdgCode() == 22) { - histos.fill(HIST("Gen/h2dGenGammaVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == 3122) { - histos.fill(HIST("Gen/h2dGenLambdaVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == -3122) { - histos.fill(HIST("Gen/h2dGenAntiLambdaVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); - } - } - if (v0MC.pdgCode() == 22) { - histos.fill(HIST("Gen/h2dGenGamma"), centrality, ptmc); - histos.fill(HIST("Gen/h2dGenGammaVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == 3122) { - histos.fill(HIST("Gen/h2dGenLambda"), centrality, ptmc); - histos.fill(HIST("Gen/h2dGenLambdaVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == -3122) { - histos.fill(HIST("Gen/h2dGenAntiLambda"), centrality, ptmc); - histos.fill(HIST("Gen/h2dGenAntiLambdaVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + if (genSelections.mc_keepOnlyFromTransport && !genSelections.mc_keepOnlyFromGenerator) { + if (mcParticle.producedByGenerator()) + continue; } - } - } - template - void runPi0QA(TV0Object const& gamma1, TV0Object const& gamma2, TCollision collision) - { - // Check if both V0s are made of the same tracks - if (gamma1.posTrackExtraId() == gamma2.posTrackExtraId() || - gamma1.negTrackExtraId() == gamma2.negTrackExtraId()) { - return; - } + // MC Process selection + if ((genSelections.mc_selectMCProcess >= 0) && (genSelections.mc_selectMCProcess != mcParticle.getProcess())) + continue; - // Calculate pi0 properties - std::array pVecGamma1{gamma1.px(), gamma1.py(), gamma1.pz()}; - std::array pVecGamma2{gamma2.px(), gamma2.py(), gamma2.pz()}; - std::array arrpi0{pVecGamma1, pVecGamma2}; - float pi0Mass = RecoDecay::m(arrpi0, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); - float pi0Pt = RecoDecay::pt(std::array{gamma1.px() + gamma2.px(), gamma1.py() + gamma2.py()}); - float pi0Y = RecoDecay::y(std::array{gamma1.px() + gamma2.px(), gamma1.py() + gamma2.py(), gamma1.pz() + gamma2.pz()}, o2::constants::physics::MassPi0); - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + // Get generated particle info + auto MCGenInfo = getV0PairGenInfo(mcParticle); - // MC-specific variables - bool fIsPi0 = false, fIsMC = false; + // Fill QA histos + if (genSelections.doQA) + fillGenQAHistos(MCGenInfo); - // Check if MC data and populate fIsMC, fIsPi0 - if constexpr (requires { gamma1.motherMCPartId(); gamma2.motherMCPartId(); }) { - if (gamma1.has_v0MCCore() && gamma2.has_v0MCCore()) { - fIsMC = true; - auto gamma1MC = gamma1.template v0MCCore_as>(); - auto gamma2MC = gamma2.template v0MCCore_as>(); - - if (gamma1MC.pdgCode() == 22 && gamma2MC.pdgCode() == 22 && - gamma1MC.pdgCodeMother() == 111 && gamma2MC.pdgCodeMother() == 111 && - gamma1.motherMCPartId() == gamma2.motherMCPartId()) { - fIsPi0 = true; - histos.fill(HIST("Pi0QA/h3dMassPi0BeforeSel_MCAssoc"), centrality, pi0Pt, pi0Mass); - } + // Fill tables + // Pi0 + if (fillPi0Tables && MCGenInfo.IsPi0) { + pi0Gens(MCGenInfo.IsProducedByGenerator, MCGenInfo.MCPt); // optional table to store generated pi0 candidates. Be careful, this is a large table! + pi0GenCollRefs(MCGenInfo.MCCollId); // link to stramccollision table } - } - - histos.fill(HIST("Pi0QA/h3dMassPi0BeforeSel_Candidates"), centrality, pi0Pt, pi0Mass); - - // Photon-specific selections - auto posTrackGamma1 = gamma1.template posTrackExtra_as(); - auto negTrackGamma1 = gamma1.template negTrackExtra_as(); - auto posTrackGamma2 = gamma2.template posTrackExtra_as(); - auto negTrackGamma2 = gamma2.template negTrackExtra_as(); - - // Gamma1 Selection - bool passedTPCGamma1 = (TMath::Abs(posTrackGamma1.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas) || - (TMath::Abs(negTrackGamma1.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas); - - if (TMath::Abs(gamma1.mGamma()) > Pi0PhotonMaxMass || - gamma1.qtarm() >= Pi0PhotonMaxQt || - TMath::Abs(gamma1.alpha()) >= Pi0PhotonMaxAlpha || - TMath::Abs(gamma1.dcapostopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma1.dcanegtopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma1.dcaV0daughters()) > Pi0PhotonMaxDCAV0Dau || - TMath::Abs(gamma1.negativeeta()) >= Pi0PhotonMaxEta || - TMath::Abs(gamma1.positiveeta()) >= Pi0PhotonMaxEta || - gamma1.v0cosPA() <= Pi0PhotonMinV0cospa || - gamma1.v0radius() <= Pi0PhotonMinRadius || - gamma1.v0radius() >= Pi0PhotonMaxRadius || - posTrackGamma1.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - negTrackGamma1.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - !passedTPCGamma1) { - return; - } - // Gamma2 Selection - bool passedTPCGamma2 = (TMath::Abs(posTrackGamma2.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas) || - (TMath::Abs(negTrackGamma2.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas); - - if (TMath::Abs(gamma2.mGamma()) > Pi0PhotonMaxMass || - gamma2.qtarm() >= Pi0PhotonMaxQt || - TMath::Abs(gamma2.alpha()) >= Pi0PhotonMaxAlpha || - TMath::Abs(gamma2.dcapostopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma2.dcanegtopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma2.dcaV0daughters()) > Pi0PhotonMaxDCAV0Dau || - TMath::Abs(gamma2.negativeeta()) >= Pi0PhotonMaxEta || - TMath::Abs(gamma2.positiveeta()) >= Pi0PhotonMaxEta || - gamma2.v0cosPA() <= Pi0PhotonMinV0cospa || - gamma2.v0radius() <= Pi0PhotonMinRadius || - gamma2.v0radius() >= Pi0PhotonMaxRadius || - posTrackGamma2.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - negTrackGamma2.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - !passedTPCGamma2) { - return; - } - - // Pi0-specific selections: - if (TMath::Abs(pi0Y) > 0.5) { - return; + // Sigma0/ASigma0 + if (fillSigma0Tables && (MCGenInfo.IsSigma0 || MCGenInfo.IsAntiSigma0)) { + sigma0Gens(MCGenInfo.IsSigma0, MCGenInfo.IsProducedByGenerator, MCGenInfo.MCPt); + sigma0GenCollRefs(MCGenInfo.MCCollId); // link to stramccollision table + } } - - // Fill histograms - histos.fill(HIST("Pi0QA/h3dMassPi0AfterSel_Candidates"), centrality, pi0Pt, pi0Mass); - if (fIsMC && fIsPi0) - histos.fill(HIST("Pi0QA/h3dMassPi0AfterSel_MCAssoc"), centrality, pi0Pt, pi0Mass); } + //_______________________________________________ // Process photon candidate template - bool processPhotonCandidate(TV0Object const& gamma, TCollision collision) + bool processPhotonCandidate(TV0Object const& gamma, TCollision const& collision) { + // V0 type selection if (gamma.v0Type() == 0) return false; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + float PhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); + histos.fill(HIST("PhotonSel/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); + histos.fill(HIST("PhotonSel/h2dMassGammaVsLambda"), gamma.mGamma(), gamma.mLambda()); + if (useMLScores) { - // Gamma selection: if (gamma.gammaBDTScore() <= Gamma_MLThreshold) return false; @@ -853,7 +701,6 @@ struct sigma0builder { histos.fill(HIST("PhotonSel/hPhotonMass"), gamma.mGamma()); if ((gamma.mGamma() < 0) || (gamma.mGamma() > PhotonMaxMass)) return false; - float PhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); histos.fill(HIST("PhotonSel/hPhotonNegEta"), gamma.negativeeta()); histos.fill(HIST("PhotonSel/hPhotonPosEta"), gamma.positiveeta()); histos.fill(HIST("PhotonSel/hPhotonY"), PhotonY); @@ -875,18 +722,38 @@ struct sigma0builder { return false; histos.fill(HIST("PhotonSel/hSelectionStatistics"), 6.); } - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + histos.fill(HIST("PhotonSel/h2dV0XY"), gamma.x(), gamma.y()); histos.fill(HIST("PhotonSel/h3dPhotonMass"), centrality, gamma.pt(), gamma.mGamma()); + + //_______________________________________________ + // MC Processing + if constexpr (requires { gamma.motherMCPartId(); }) { + if (gamma.has_v0MCCore()) { + auto gammaMC = gamma.template v0MCCore_as>(); + if (gammaMC.pdgCode() == 22) { + histos.fill(HIST("MC/h2dGammaXYConversion"), gamma.x(), gamma.y()); + histos.fill(HIST("MC/h2dPtVsCentrality_MCAssocGamma"), centrality, gamma.pt()); + } + } + } + return true; } - // Process photon candidate + //_______________________________________________ + // Process lambda candidate template - bool processLambdaCandidate(TV0Object const& lambda, TCollision collision) + bool processLambdaCandidate(TV0Object const& lambda, TCollision const& collision) { + // V0 type selection if (lambda.v0Type() != 1) return false; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + histos.fill(HIST("LambdaSel/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); + histos.fill(HIST("LambdaSel/h2dMassLambdaVsGamma"), lambda.mLambda(), lambda.mGamma()); + if (useMLScores) { if ((lambda.lambdaBDTScore() <= Lambda_MLThreshold) && (lambda.antiLambdaBDTScore() <= AntiLambda_MLThreshold)) return false; @@ -920,116 +787,152 @@ struct sigma0builder { histos.fill(HIST("LambdaSel/hSelectionStatistics"), 6.); } - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); histos.fill(HIST("LambdaSel/h3dLambdaMass"), centrality, lambda.pt(), lambda.mLambda()); histos.fill(HIST("LambdaSel/h3dALambdaMass"), centrality, lambda.pt(), lambda.mAntiLambda()); + //_______________________________________________ + // MC Processing (if available) + if constexpr (requires { lambda.motherMCPartId(); }) { + if (lambda.has_v0MCCore()) { + auto lambdaMC = lambda.template v0MCCore_as>(); + if (lambdaMC.pdgCode() == 3122) // Is Lambda + histos.fill(HIST("MC/h2dPtVsCentrality_MCAssocLambda"), centrality, lambda.pt()); + if (lambdaMC.pdgCode() == -3122) // Is AntiLambda + histos.fill(HIST("MC/h2dPtVsCentrality_MCAssocALambda"), centrality, lambda.pt()); + } + } + return true; } - /////////// - // Process sigma candidate and store properties in object - template - bool buildSigma0(TV0Object const& lambda, TV0Object const& gamma, TCollision collision) + + //_______________________________________________ + // Build pi0 candidate for QA + template + bool buildPi0(TV0Object const& gamma1, TV0Object const& gamma2, TCollision const& collision, TMCParticles const& mcparticles) { + //_______________________________________________ + // Check if both V0s are made of the same tracks + if (gamma1.posTrackExtraId() == gamma2.posTrackExtraId() || + gamma1.negTrackExtraId() == gamma2.negTrackExtraId()) { + return false; + } + + //_______________________________________________ + // Calculate pi0 properties + std::array pVecGamma1{gamma1.px(), gamma1.py(), gamma1.pz()}; + std::array pVecGamma2{gamma2.px(), gamma2.py(), gamma2.pz()}; + std::array arrpi0{pVecGamma1, pVecGamma2}; + float pi0Mass = RecoDecay::m(arrpi0, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); + float pi0Y = RecoDecay::y(std::array{gamma1.px() + gamma2.px(), gamma1.py() + gamma2.py(), gamma1.pz() + gamma2.pz()}, o2::constants::physics::MassPi0); + + //_______________________________________________ + // Pi0-specific selections: + if (TMath::Abs(pi0Y) > Pi0MaxRap) + return false; + + if (TMath::Abs(pi0Mass - o2::constants::physics::MassPi0) > Pi0MassWindow) + return false; + + // Fill optional tables for QA + // Define the table! + auto posTrackGamma1 = gamma1.template posTrackExtra_as(); + auto negTrackGamma1 = gamma1.template negTrackExtra_as(); + auto posTrackGamma2 = gamma2.template posTrackExtra_as(); + auto negTrackGamma2 = gamma2.template negTrackExtra_as(); + + // Calculate Pi0 topological info + auto pi0TopoInfo = propagateV0PairToDCA(gamma1, gamma2); + + // Check if MC data and populate corresponding table + if constexpr (requires { gamma1.motherMCPartId(); gamma2.motherMCPartId(); }) { + auto pi0MCInfo = getV0PairMCInfo(gamma1, gamma2, collision, mcparticles); + + pi0coresmc(pi0MCInfo.V0PairMCRadius, pi0MCInfo.V0PairPDGCode, pi0MCInfo.V0PairPDGCodeMother, pi0MCInfo.V0PairMCProcess, pi0MCInfo.fV0PairProducedByGenerator, + pi0MCInfo.V01MCpx, pi0MCInfo.V01MCpy, pi0MCInfo.V01MCpz, + pi0MCInfo.fIsV01Primary, pi0MCInfo.V01PDGCode, pi0MCInfo.V01PDGCodeMother, pi0MCInfo.fIsV01CorrectlyAssign, + pi0MCInfo.V02MCpx, pi0MCInfo.V02MCpy, pi0MCInfo.V02MCpz, + pi0MCInfo.fIsV02Primary, pi0MCInfo.V02PDGCode, pi0MCInfo.V02PDGCodeMother, pi0MCInfo.fIsV02CorrectlyAssign); + } + + pi0cores(pi0TopoInfo.X, pi0TopoInfo.Y, pi0TopoInfo.Z, pi0TopoInfo.DCADau, pi0TopoInfo.CosPA, + gamma1.px(), gamma1.py(), gamma1.pz(), + gamma1.mGamma(), gamma1.qtarm(), gamma1.alpha(), gamma1.dcapostopv(), gamma1.dcanegtopv(), gamma1.dcaV0daughters(), + gamma1.negativeeta(), gamma1.positiveeta(), gamma1.v0cosPA(), gamma1.v0radius(), gamma1.z(), + posTrackGamma1.tpcCrossedRows(), negTrackGamma1.tpcCrossedRows(), posTrackGamma1.tpcNSigmaEl(), negTrackGamma1.tpcNSigmaEl(), gamma1.v0Type(), + gamma2.px(), gamma2.py(), gamma2.pz(), + gamma2.mGamma(), gamma2.qtarm(), gamma2.alpha(), gamma2.dcapostopv(), gamma2.dcanegtopv(), gamma2.dcaV0daughters(), + gamma2.negativeeta(), gamma2.positiveeta(), gamma2.v0cosPA(), gamma2.v0radius(), gamma2.z(), + posTrackGamma2.tpcCrossedRows(), negTrackGamma2.tpcCrossedRows(), posTrackGamma2.tpcNSigmaEl(), negTrackGamma2.tpcNSigmaEl(), gamma2.v0Type()); + + pi0coresRefs(collision.globalIndex()); + + return true; + } + + //_______________________________________________ + // Build sigma0 candidate + template + bool buildSigma0(TV0Object const& lambda, TV0Object const& gamma, TCollision const& collision, TMCParticles const& mcparticles) + { + //_______________________________________________ // Checking if both V0s are made of the very same tracks if (gamma.posTrackExtraId() == lambda.posTrackExtraId() || gamma.negTrackExtraId() == lambda.negTrackExtraId()) { return false; } - // Sigma0 candidate properties + //_______________________________________________ + // Sigma0 pre-selections std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; float sigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - float sigmaY = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); - float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + float sigmaY = -999.f; - // Before any selection - histos.fill(HIST("SigmaSel/h3dMassSigma0BeforeSel"), centrality, SigmapT, sigmaMass); + if constexpr (requires { gamma.pxMC(); lambda.pxMC(); }) // If MC + sigmaY = RecoDecay::y(std::array{gamma.pxMC() + lambda.pxMC(), gamma.pyMC() + lambda.pyMC(), gamma.pzMC() + lambda.pzMC()}, o2::constants::physics::MassSigma0); + else // If DATA + sigmaY = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); histos.fill(HIST("SigmaSel/hSelectionStatistics"), 1.); - histos.fill(HIST("SigmaSel/hSigmaMass"), sigmaMass); - histos.fill(HIST("SigmaSel/hSigmaMassWindow"), sigmaMass - 1.192642); - - if (fillQAhistos) { - histos.fill(HIST("GeneralQA/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassGammaVsLambda"), gamma.mGamma(), gamma.mLambda()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsGamma"), lambda.mLambda(), lambda.mGamma()); - histos.fill(HIST("GeneralQA/h3dMassSigma0VsDaupTs"), gamma.pt(), lambda.pt(), sigmaMass); - } - - if (TMath::Abs(sigmaMass - 1.192642) > Sigma0Window) + if (TMath::Abs(sigmaMass - o2::constants::physics::MassSigma0) > Sigma0Window) return false; - histos.fill(HIST("SigmaSel/hSigmaY"), sigmaY); histos.fill(HIST("SigmaSel/hSelectionStatistics"), 2.); - if (TMath::Abs(sigmaY) > SigmaMaxRap) return false; histos.fill(HIST("SigmaSel/hSigmaMassSelected"), sigmaMass); histos.fill(HIST("SigmaSel/hSelectionStatistics"), 3.); + //_______________________________________________ + // Calculate properties & Fill tables - if (fillQAhistos) { - histos.fill(HIST("GeneralQA/h2dMassGammaVsK0SAfterMassSel"), gamma.mGamma(), gamma.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0SAfterMassSel"), lambda.mLambda(), lambda.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassGammaVsLambdaAfterMassSel"), gamma.mGamma(), lambda.mLambda()); - histos.fill(HIST("GeneralQA/h2dV0XY"), gamma.x(), gamma.y()); - } + // Sigma0 topological info + auto sigma0TopoInfo = propagateV0PairToDCA(gamma, lambda); - histos.fill(HIST("SigmaSel/h3dMassSigma0AfterSel"), centrality, SigmapT, sigmaMass); + sigma0cores(sigma0TopoInfo.X, sigma0TopoInfo.Y, sigma0TopoInfo.Z, sigma0TopoInfo.DCADau, + gamma.px(), gamma.py(), gamma.pz(), gamma.mGamma(), lambda.px(), lambda.py(), lambda.pz(), lambda.mLambda(), lambda.mAntiLambda()); - return true; - } + // MC properties + if constexpr (requires { gamma.motherMCPartId(); lambda.motherMCPartId(); }) { + auto sigma0MCInfo = getV0PairMCInfo(gamma, lambda, collision, mcparticles); - // Fill tables with reconstructed sigma0 candidate - template - void fillTables(TV0Object const& lambda, TV0Object const& gamma, TCollision const& coll) - { - float GammaBDTScore = gamma.gammaBDTScore(); - float LambdaBDTScore = lambda.lambdaBDTScore(); - float AntiLambdaBDTScore = lambda.antiLambdaBDTScore(); + sigma0mccores(sigma0MCInfo.V0PairMCRadius, sigma0MCInfo.V0PairPDGCode, sigma0MCInfo.V0PairPDGCodeMother, sigma0MCInfo.V0PairMCProcess, sigma0MCInfo.fV0PairProducedByGenerator, + sigma0MCInfo.V01MCpx, sigma0MCInfo.V01MCpy, sigma0MCInfo.V01MCpz, + sigma0MCInfo.fIsV01Primary, sigma0MCInfo.V01PDGCode, sigma0MCInfo.V01PDGCodeMother, sigma0MCInfo.fIsV01CorrectlyAssign, + sigma0MCInfo.V02MCpx, sigma0MCInfo.V02MCpy, sigma0MCInfo.V02MCpz, + sigma0MCInfo.fIsV02Primary, sigma0MCInfo.V02PDGCode, sigma0MCInfo.V02PDGCodeMother, sigma0MCInfo.fIsV02CorrectlyAssign); + } + + // Sigma0s -> stracollisions link + sigma0CollRefs(collision.globalIndex()); - // Daughters related - /// Photon + //_______________________________________________ + // Photon extra properties auto posTrackGamma = gamma.template posTrackExtra_as(); auto negTrackGamma = gamma.template negTrackExtra_as(); - float fPhotonPt = gamma.pt(); - float fPhotonMass = gamma.mGamma(); - float fPhotonQt = gamma.qtarm(); - float fPhotonAlpha = gamma.alpha(); - float fPhotonRadius = gamma.v0radius(); - float fPhotonCosPA = gamma.v0cosPA(); - float fPhotonDCADau = gamma.dcaV0daughters(); - float fPhotonDCANegPV = gamma.dcanegtopv(); - float fPhotonDCAPosPV = gamma.dcapostopv(); - float fPhotonZconv = gamma.z(); - float fPhotonEta = gamma.eta(); - float fPhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); - float fPhotonPhi = RecoDecay::phi(gamma.px(), gamma.py()); - float fPhotonPosTPCNSigmaEl = posTrackGamma.tpcNSigmaEl(); - float fPhotonNegTPCNSigmaEl = negTrackGamma.tpcNSigmaEl(); - float fPhotonPosTPCNSigmaPi = posTrackGamma.tpcNSigmaPi(); - float fPhotonNegTPCNSigmaPi = negTrackGamma.tpcNSigmaPi(); - uint8_t fPhotonPosTPCCrossedRows = posTrackGamma.tpcCrossedRows(); - uint8_t fPhotonNegTPCCrossedRows = negTrackGamma.tpcCrossedRows(); - float fPhotonPosPt = gamma.positivept(); - float fPhotonNegPt = gamma.negativept(); - float fPhotonPosEta = gamma.positiveeta(); - float fPhotonNegEta = gamma.negativeeta(); - float fPhotonPosY = RecoDecay::y(std::array{gamma.pxpos(), gamma.pypos(), gamma.pzpos()}, o2::constants::physics::MassElectron); - float fPhotonNegY = RecoDecay::y(std::array{gamma.pxneg(), gamma.pyneg(), gamma.pzneg()}, o2::constants::physics::MassElectron); - float fPhotonPsiPair = gamma.psipair(); - int fPhotonPosITSCls = posTrackGamma.itsNCls(); - int fPhotonNegITSCls = negTrackGamma.itsNCls(); - float fPhotonPosITSChi2PerNcl = posTrackGamma.itsChi2PerNcl(); - float fPhotonNegITSChi2PerNcl = negTrackGamma.itsChi2PerNcl(); - uint8_t fPhotonV0Type = gamma.v0Type(); - uint8_t fPhotonPosTrackCode = ((uint8_t(posTrackGamma.hasTPC()) << hasTPC) | (uint8_t(posTrackGamma.hasITSTracker()) << hasITSTracker) | (uint8_t(posTrackGamma.hasITSAfterburner()) << hasITSAfterburner) | @@ -1042,50 +945,16 @@ struct sigma0builder { (uint8_t(negTrackGamma.hasTRD()) << hasTRD) | (uint8_t(negTrackGamma.hasTOF()) << hasTOF)); - // Lambda + sigmaPhotonExtras(gamma.qtarm(), gamma.alpha(), gamma.v0cosPA(), gamma.dcaV0daughters(), gamma.dcanegtopv(), gamma.dcapostopv(), gamma.v0radius(), gamma.z(), + posTrackGamma.tpcNSigmaEl(), negTrackGamma.tpcNSigmaEl(), posTrackGamma.tpcCrossedRows(), negTrackGamma.tpcCrossedRows(), + gamma.positiveeta(), gamma.negativeeta(), gamma.psipair(), posTrackGamma.itsNCls(), negTrackGamma.itsNCls(), posTrackGamma.itsChi2PerNcl(), negTrackGamma.itsChi2PerNcl(), + fPhotonPosTrackCode, fPhotonNegTrackCode, gamma.v0Type()); + + //_______________________________________________ + // Lambda extra properties auto posTrackLambda = lambda.template posTrackExtra_as(); auto negTrackLambda = lambda.template negTrackExtra_as(); - float fLambdaPt = lambda.pt(); - float fLambdaMass = lambda.mLambda(); - float fAntiLambdaMass = lambda.mAntiLambda(); - float fLambdaQt = lambda.qtarm(); - float fLambdaAlpha = lambda.alpha(); - float fLambdaLifeTime = lambda.distovertotmom(coll.posX(), coll.posY(), coll.posZ()) * o2::constants::physics::MassLambda0; - float fLambdaRadius = lambda.v0radius(); - float fLambdaCosPA = lambda.v0cosPA(); - float fLambdaDCADau = lambda.dcaV0daughters(); - float fLambdaDCANegPV = lambda.dcanegtopv(); - float fLambdaDCAPosPV = lambda.dcapostopv(); - float fLambdaEta = lambda.eta(); - float fLambdaY = lambda.yLambda(); - float fLambdaPhi = RecoDecay::phi(lambda.px(), lambda.py()); - float fLambdaPosPrTPCNSigma = posTrackLambda.tpcNSigmaPr(); - float fLambdaPosPiTPCNSigma = posTrackLambda.tpcNSigmaPi(); - float fLambdaNegPrTPCNSigma = negTrackLambda.tpcNSigmaPr(); - float fLambdaNegPiTPCNSigma = negTrackLambda.tpcNSigmaPi(); - - float fLambdaPrTOFNSigma = lambda.tofNSigmaLaPr(); - float fLambdaPiTOFNSigma = lambda.tofNSigmaLaPi(); - float fALambdaPrTOFNSigma = lambda.tofNSigmaALaPr(); - float fALambdaPiTOFNSigma = lambda.tofNSigmaALaPi(); - - uint8_t fLambdaPosTPCCrossedRows = posTrackLambda.tpcCrossedRows(); - uint8_t fLambdaNegTPCCrossedRows = negTrackLambda.tpcCrossedRows(); - float fLambdaPosPt = lambda.positivept(); - float fLambdaNegPt = lambda.negativept(); - float fLambdaPosEta = lambda.positiveeta(); - float fLambdaNegEta = lambda.negativeeta(); - float fLambdaPosPrY = RecoDecay::y(std::array{lambda.pxpos(), lambda.pypos(), lambda.pzpos()}, o2::constants::physics::MassProton); - float fLambdaPosPiY = RecoDecay::y(std::array{lambda.pxpos(), lambda.pypos(), lambda.pzpos()}, o2::constants::physics::MassPionCharged); - float fLambdaNegPrY = RecoDecay::y(std::array{lambda.pxneg(), lambda.pyneg(), lambda.pzneg()}, o2::constants::physics::MassProton); - float fLambdaNegPiY = RecoDecay::y(std::array{lambda.pxneg(), lambda.pyneg(), lambda.pzneg()}, o2::constants::physics::MassPionCharged); - int fLambdaPosITSCls = posTrackLambda.itsNCls(); - int fLambdaNegITSCls = negTrackLambda.itsNCls(); - float fLambdaPosITSChi2PerNcl = posTrackLambda.itsChi2PerNcl(); - float fLambdaNegITSChi2PerNcl = negTrackLambda.itsChi2PerNcl(); - uint8_t fLambdaV0Type = lambda.v0Type(); - uint8_t fLambdaPosTrackCode = ((uint8_t(posTrackLambda.hasTPC()) << hasTPC) | (uint8_t(posTrackLambda.hasITSTracker()) << hasITSTracker) | (uint8_t(posTrackLambda.hasITSAfterburner()) << hasITSAfterburner) | @@ -1098,109 +967,62 @@ struct sigma0builder { (uint8_t(negTrackLambda.hasTRD()) << hasTRD) | (uint8_t(negTrackLambda.hasTOF()) << hasTOF)); - // Sigma0 candidate properties - std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; - std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; - auto arrMom = std::array{pVecPhotons, pVecLambda}; - TVector3 v1(gamma.px(), gamma.py(), gamma.pz()); - TVector3 v2(lambda.px(), lambda.py(), lambda.pz()); - - // Sigma related - float fSigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - float fSigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - float fSigmaRap = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); - float fSigmaOPAngle = v1.Angle(v2); - float fSigmaCentrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); - uint64_t fSigmaTimeStamp = coll.timestamp(); - int fSigmaRunNumber = coll.runNumber(); - - // Filling TTree for ML analysis - sigma0cores(fSigmapT, fSigmaMass, fSigmaRap, fSigmaOPAngle, fSigmaCentrality, fSigmaRunNumber, fSigmaTimeStamp); - - sigmaPhotonExtras(fPhotonPt, fPhotonMass, fPhotonQt, fPhotonAlpha, fPhotonRadius, - fPhotonCosPA, fPhotonDCADau, fPhotonDCANegPV, fPhotonDCAPosPV, fPhotonZconv, - fPhotonEta, fPhotonY, fPhotonPhi, fPhotonPosTPCNSigmaEl, fPhotonNegTPCNSigmaEl, fPhotonPosTPCNSigmaPi, fPhotonNegTPCNSigmaPi, fPhotonPosTPCCrossedRows, - fPhotonNegTPCCrossedRows, fPhotonPosPt, fPhotonNegPt, fPhotonPosEta, - fPhotonNegEta, fPhotonPosY, fPhotonNegY, fPhotonPsiPair, - fPhotonPosITSCls, fPhotonNegITSCls, fPhotonPosITSChi2PerNcl, fPhotonNegITSChi2PerNcl, fPhotonPosTrackCode, fPhotonNegTrackCode, - fPhotonV0Type, GammaBDTScore); - - sigmaLambdaExtras(fLambdaPt, fLambdaMass, fAntiLambdaMass, fLambdaQt, fLambdaAlpha, fLambdaLifeTime, - fLambdaRadius, fLambdaCosPA, fLambdaDCADau, fLambdaDCANegPV, - fLambdaDCAPosPV, fLambdaEta, fLambdaY, fLambdaPhi, fLambdaPosPrTPCNSigma, - fLambdaPosPiTPCNSigma, fLambdaNegPrTPCNSigma, fLambdaNegPiTPCNSigma, + float fLambdaLifeTime = lambda.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + float fLambdaPrTOFNSigma = -999.f; + float fLambdaPiTOFNSigma = -999.f; + float fALambdaPrTOFNSigma = -999.f; + float fALambdaPiTOFNSigma = -999.f; + + if constexpr (requires { lambda.tofNSigmaLaPr(); }) { // If TOF info avaiable + fLambdaPrTOFNSigma = lambda.tofNSigmaLaPr(); + fLambdaPiTOFNSigma = lambda.tofNSigmaLaPi(); + fALambdaPrTOFNSigma = lambda.tofNSigmaALaPr(); + fALambdaPiTOFNSigma = lambda.tofNSigmaALaPi(); + } + + sigmaLambdaExtras(lambda.qtarm(), lambda.alpha(), fLambdaLifeTime, lambda.v0radius(), lambda.v0cosPA(), lambda.dcaV0daughters(), lambda.dcanegtopv(), lambda.dcapostopv(), + posTrackLambda.tpcNSigmaPr(), posTrackLambda.tpcNSigmaPi(), negTrackLambda.tpcNSigmaPr(), negTrackLambda.tpcNSigmaPi(), fLambdaPrTOFNSigma, fLambdaPiTOFNSigma, fALambdaPrTOFNSigma, fALambdaPiTOFNSigma, - fLambdaPosTPCCrossedRows, fLambdaNegTPCCrossedRows, fLambdaPosPt, fLambdaNegPt, fLambdaPosEta, - fLambdaNegEta, fLambdaPosPrY, fLambdaPosPiY, fLambdaNegPrY, fLambdaNegPiY, - fLambdaPosITSCls, fLambdaNegITSCls, fLambdaPosITSChi2PerNcl, fLambdaNegITSChi2PerNcl, fLambdaPosTrackCode, fLambdaNegTrackCode, - fLambdaV0Type, LambdaBDTScore, AntiLambdaBDTScore); + posTrackLambda.tpcCrossedRows(), negTrackLambda.tpcCrossedRows(), + lambda.positiveeta(), lambda.negativeeta(), + posTrackLambda.itsNCls(), negTrackLambda.itsNCls(), posTrackLambda.itsChi2PerNcl(), negTrackLambda.itsChi2PerNcl(), + fLambdaPosTrackCode, fLambdaNegTrackCode, lambda.v0Type()); + + return true; } - void processMonteCarlo(soa::Join const& collisions, V0DerivedMCDatas const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + // Process photon and lambda candidates to build sigma0 candidates + template + void dataProcess(TCollision const& collisions, TV0s const& fullV0s, TMCParticles const& mcparticles) { - // Initialize auxiliary vectors + //_______________________________________________ + // Initial setup + // Auxiliary vectors to store best candidates std::vector bestGammasArray; std::vector bestLambdasArray; - // brute force grouped index construction + // Custom grouping std::vector> v0grouped(collisions.size()); for (const auto& v0 : fullV0s) { v0grouped[v0.straCollisionId()].push_back(v0.globalIndex()); } + //_______________________________________________ + // Collisions loop for (const auto& coll : collisions) { // Clear vectors bestGammasArray.clear(); bestLambdasArray.clear(); - if (!IsEventAccepted(coll, true)) - continue; - float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); - - bool fhasMCColl = false; - if (coll.has_straMCCollision()) - fhasMCColl = true; - - //_______________________________________________ - // Retrieving IR info - float interactionRate = -1; - if (fGetIR) { - interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; - if (interactionRate < 0) - histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", coll.runNumber()), 1); - - histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); - } + histos.fill(HIST("hEventCentrality"), centrality); //_______________________________________________ // V0s loop for (size_t i = 0; i < v0grouped[coll.globalIndex()].size(); i++) { auto v0 = fullV0s.rawIteratorAt(v0grouped[coll.globalIndex()][i]); - if (!v0.has_v0MCCore()) - continue; - - auto v0MC = v0.v0MCCore_as>(); - - if (v0MC.pdgCode() == 22) { - histos.fill(HIST("MC/h2dGammaXYConversion"), v0.x(), v0.y()); - float GammaY = TMath::Abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma)); - if (GammaY < 0.5) { // rapidity selection - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocGamma"), centrality, v0.pt()); // isgamma - } - } - - float lambdaY = TMath::Abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassLambda)); - if (lambdaY < 0.5) { - if (v0MC.pdgCode() == 3122) // Is Lambda - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocLambda"), centrality, v0.pt()); - if (v0MC.pdgCode() == -3122) // Is AntiLambda - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocALambda"), centrality, v0.pt()); - } - if (processPhotonCandidate(v0, coll)) // selecting photons bestGammasArray.push_back(v0.globalIndex()); // Save indices of best gamma candidates @@ -1209,117 +1031,41 @@ struct sigma0builder { } //_______________________________________________ - // Pi0 optional loop - if (doPi0QA) { - for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); - for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { - auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); - runPi0QA(gamma1, gamma2, coll); - } + // Wrongly collision association study (MC-specific) + if constexpr (requires { coll.StraMCCollisionId(); }) { + if (doAssocStudy) { + analyzeV0CollAssoc(coll, fullV0s, bestGammasArray, true); // Photon-analysis + analyzeV0CollAssoc(coll, fullV0s, bestLambdasArray, false); // Lambda-analysis } } //_______________________________________________ - // Wrongly collision association study - if (doAssocStudy && fhasMCColl) { - analyzeV0CollAssoc(coll, fullV0s, bestGammasArray, interactionRate, true); // Gamma - analyzeV0CollAssoc(coll, fullV0s, bestLambdasArray, interactionRate, false); // Lambda - } - - //_______________________________________________ - // Sigma0 loop + // V0 nested loop for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma = fullV0s.rawIteratorAt(bestGammasArray[i]); - - if (!gamma.has_v0MCCore()) - continue; + auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); - auto gammaMC = gamma.v0MCCore_as>(); + //_______________________________________________ + // Sigma0 loop + if (fillSigma0Tables) { + for (size_t j = 0; j < bestLambdasArray.size(); ++j) { + auto lambda = fullV0s.rawIteratorAt(bestLambdasArray[j]); - bool fIsPhotonCorrectlyAssign = false; - if (fhasMCColl) { - auto gammaMCCollision = coll.template straMCCollision_as>(); - fIsPhotonCorrectlyAssign = (gammaMC.straMCCollisionId() == gammaMCCollision.globalIndex()); - } - - for (size_t j = 0; j < bestLambdasArray.size(); ++j) { - auto lambda = fullV0s.rawIteratorAt(bestLambdasArray[j]); - - if (!lambda.has_v0MCCore()) - continue; - - auto lambdaMC = lambda.v0MCCore_as>(); - - // Sigma0 candidate properties - std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; - std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; - auto arrMom = std::array{pVecPhotons, pVecLambda}; - float SigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - float SigmaY = TMath::Abs(RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0)); - - // MC properties - bool fIsSigma = false; - bool fIsAntiSigma = false; - bool fIsPhotonPrimary = gammaMC.isPhysicalPrimary(); - bool fIsLambdaPrimary = lambdaMC.isPhysicalPrimary(); - bool fIsLambdaCorrectlyAssign = false; - - int PhotonCandPDGCode = gammaMC.pdgCode(); - int PhotonCandPDGCodeMother = gammaMC.pdgCodeMother(); - int LambdaCandPDGCode = lambdaMC.pdgCode(); - int LambdaCandPDGCodeMother = lambdaMC.pdgCodeMother(); - - float SigmaMCpT = RecoDecay::pt(array{gammaMC.pxMC() + lambdaMC.pxMC(), gammaMC.pyMC() + lambdaMC.pyMC()}); - float PhotonMCpT = RecoDecay::pt(array{gammaMC.pxMC(), gammaMC.pyMC()}); - float LambdaMCpT = RecoDecay::pt(array{lambdaMC.pxMC(), lambdaMC.pyMC()}); - - if (fhasMCColl) { - auto lambdaMCCollision = coll.template straMCCollision_as>(); - fIsLambdaCorrectlyAssign = (lambdaMC.straMCCollisionId() == lambdaMCCollision.globalIndex()); - } - - if ((PhotonCandPDGCode == 22) && (PhotonCandPDGCodeMother == 3212) && (LambdaCandPDGCode == 3122) && (LambdaCandPDGCodeMother == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) - fIsSigma = true; - if ((PhotonCandPDGCode == 22) && (PhotonCandPDGCodeMother == -3212) && (LambdaCandPDGCode == -3122) && (LambdaCandPDGCodeMother == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) - fIsAntiSigma = true; - - if (SigmaY < 0.5) { - if (fIsSigma) { - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocSigma0"), centrality, SigmaMCpT); - histos.fill(HIST("MC/h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc"), SigmaMCpT, LambdaMCpT); - histos.fill(HIST("MC/h2dSigma0PtVsGammaPtBeforeSel_MCAssoc"), SigmaMCpT, PhotonMCpT); - } - if (fIsAntiSigma) - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocASigma0"), centrality, SigmaMCpT); + // Building sigma0 candidate & filling tables + if (!buildSigma0(lambda, gamma1, coll, mcparticles)) + continue; } + } - // Build sigma0 candidate, please - if (!buildSigma0(lambda, gamma, coll)) - continue; + //_______________________________________________ + // pi0 loop + if (fillPi0Tables) { + for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { + auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); - if (SigmaY < 0.5) { - if (fIsSigma) - histos.fill(HIST("MC/h2dPtVsCentralityAfterSel_MCAssocSigma0"), centrality, SigmaMCpT); - if (fIsAntiSigma) - histos.fill(HIST("MC/h2dPtVsCentralityAfterSel_MCAssocASigma0"), centrality, SigmaMCpT); + // Building pi0 candidate & filling tables + if (!buildPi0(gamma1, gamma2, coll, mcparticles)) + continue; } - - if (fillBkgQAhistos) - runBkgAnalysis(fIsSigma, fIsAntiSigma, PhotonCandPDGCode, PhotonCandPDGCodeMother, LambdaCandPDGCode, LambdaCandPDGCodeMother, SigmapT, SigmaMass); - - // Fill Tables please - sigma0mccores(fIsSigma, fIsAntiSigma, SigmaMCpT, - PhotonCandPDGCode, PhotonCandPDGCodeMother, fIsPhotonPrimary, PhotonMCpT, fIsPhotonCorrectlyAssign, - LambdaCandPDGCode, LambdaCandPDGCodeMother, fIsLambdaPrimary, LambdaMCpT, fIsLambdaCorrectlyAssign); - - // Filling tables with accepted candidates - fillTables(lambda, gamma, coll); - - nSigmaCandidates++; - if (nSigmaCandidates % 10000 == 0) - LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; } } } @@ -1327,94 +1073,35 @@ struct sigma0builder { void processRealData(soa::Join const& collisions, V0StandardDerivedDatas const& fullV0s, dauTracks const&) { - // Initialize auxiliary vectors - std::vector bestGammasArray; - std::vector bestLambdasArray; - - // brute force grouped index construction - std::vector> v0grouped(collisions.size()); - - for (const auto& v0 : fullV0s) { - v0grouped[v0.straCollisionId()].push_back(v0.globalIndex()); - } - - for (const auto& coll : collisions) { - // Clear vectors - bestGammasArray.clear(); - bestLambdasArray.clear(); - - if (!IsEventAccepted(coll, true)) - continue; - - float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); - - //_______________________________________________ - // Retrieving IR info - float interactionRate = -1; - if (fGetIR) { - interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; - if (interactionRate < 0) - histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", coll.runNumber()), 1); - - histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); - } - - //_______________________________________________ - // V0s loop - for (size_t i = 0; i < v0grouped[coll.globalIndex()].size(); i++) { - auto v0 = fullV0s.rawIteratorAt(v0grouped[coll.globalIndex()][i]); - if (processPhotonCandidate(v0, coll)) // selecting photons - bestGammasArray.push_back(v0.globalIndex()); // Save indices of best gamma candidates - - if (processLambdaCandidate(v0, coll)) // selecting lambdas - bestLambdasArray.push_back(v0.globalIndex()); // Save indices of best lambda candidates - } - - //_______________________________________________ - // Pi0 optional loop - if (doPi0QA) { - for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); - for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { - auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); - runPi0QA(gamma1, gamma2, coll); - } - } - } - - //_______________________________________________ - // Sigma0 nested loop - for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma = fullV0s.rawIteratorAt(bestGammasArray[i]); - - for (size_t j = 0; j < bestLambdasArray.size(); ++j) { - auto lambda = fullV0s.rawIteratorAt(bestLambdasArray[j]); + dataProcess(collisions, fullV0s, nullptr); + } - // Building sigma0 candidate - if (!buildSigma0(lambda, gamma, coll)) - continue; + void processRealDataWithTOF(soa::Join const& collisions, V0TOFStandardDerivedDatas const& fullV0s, dauTracks const&) + { + dataProcess(collisions, fullV0s, nullptr); + } - // Filling tables with accepted candidates - fillTables(lambda, gamma, coll); + void processMonteCarlo(soa::Join const& collisions, V0DerivedMCDatas const& fullV0s, aod::McParticles const& mcParticles, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + { + dataProcess(collisions, fullV0s, mcParticles); + } - nSigmaCandidates++; - if (nSigmaCandidates % 10000 == 0) - LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; - } - } - } + void processMonteCarloWithTOF(soa::Join const& collisions, V0TOFDerivedMCDatas const& fullV0s, aod::McParticles const& mcParticles, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + { + dataProcess(collisions, fullV0s, mcParticles); } - // Simulated processing in Run 3 (subscribes to MC information too) - void processGeneratedRun3(soa::Join const& mcCollisions, soa::Join const& V0MCCores, soa::Join const& collisions) + // Simulated processing in Run 3 - run this over original AO2Ds + void processGeneratedRun3(aod::McParticles const& mcParticles) { - analyzeGeneratedV0s(mcCollisions, V0MCCores, collisions); + genProcess(mcParticles); } - PROCESS_SWITCH(sigma0builder, processMonteCarlo, "process as if MC data", false); PROCESS_SWITCH(sigma0builder, processRealData, "process as if real data", true); - PROCESS_SWITCH(sigma0builder, processGeneratedRun3, "process generated MC collisions", false); + PROCESS_SWITCH(sigma0builder, processRealDataWithTOF, "process as if real data", false); + PROCESS_SWITCH(sigma0builder, processMonteCarlo, "process as if MC data", false); + PROCESS_SWITCH(sigma0builder, processMonteCarloWithTOF, "process as if MC data, uses TOF PID info", false); + PROCESS_SWITCH(sigma0builder, processGeneratedRun3, "process generated MC info", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx index d7012626b4f..b4b2d393ec2 100644 --- a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx @@ -644,6 +644,7 @@ struct StrangenessBuilder { histos.add("DeduplicationQA/hBestPA", "hBestPA", kTH1F, {{200, 0.0f, 0.4f}}); histos.add("DeduplicationQA/hBestDCADau", "hBestDCADau", kTH1F, {{200, -10.0f, 10.0f}}); histos.add("DeduplicationQA/hBestMLScore", "hBestMLScore", kTH1F, {{200, 0.0f, 1.0f}}); + histos.add("DeduplicationQA/hPAOfBestMLScore", "hPAOfBestMLScore", kTH1F, {{200, 0.0f, 0.4f}}); } auto hPrimaryV0s = histos.add("hPrimaryV0s", "hPrimaryV0s", kTH1D, {{2, -0.5f, 1.5f}}); @@ -1001,8 +1002,10 @@ struct StrangenessBuilder { V0DuplicateExtras[bestPointingAngleIndex].isBestPA = true; if (bestDCADaughtersIndex != static_cast(-1)) V0DuplicateExtras[bestDCADaughtersIndex].isBestDCADau = true; - if (bestMLScoreIndex != static_cast(-1)) + if (bestMLScoreIndex != static_cast(-1)) { V0DuplicateExtras[bestMLScoreIndex].isBestMLScore = true; + histos.fill(HIST("DeduplicationQA/hPAOfBestMLScore"), V0DuplicateExtras[bestMLScoreIndex].PA); + } // return vector with duplicates info return V0DuplicateExtras; diff --git a/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx b/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx index 75cb771dbea..f74a6d95d1d 100644 --- a/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx @@ -49,6 +49,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/Track.h" #include @@ -71,7 +72,9 @@ using TracksWithAllExtras = soa::Join; using V0DerivedDatas = soa::Join; +using V0DerivedDatasMC = soa::Join; using CascDerivedDatas = soa::Join; +using CascDerivedDatasMC = soa::Join; struct strangenesstofpid { // TOF pid for strangeness (recalculated with topology) @@ -87,18 +90,41 @@ struct strangenesstofpid { // mean vertex position to be used if no collision associated o2::dataformats::MeanVertexObject* mVtx = nullptr; + // LUT for Propagator + TrackLTIntegral + o2::base::MatLayerCylSet* lut = nullptr; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // master switches + Configurable calculationMethod{"calculationMethod", 0, "algorithm for TOF calculation. 0: fast analytical withouot eloss, 1: O2 Propagator + trackLTIntegral (slow), 2: both methods and do comparison studies (slow)"}; Configurable calculateV0s{"calculateV0s", -1, "calculate V0-related TOF PID (0: no, 1: yes, -1: auto)"}; Configurable calculateCascades{"calculateCascades", -1, "calculate cascade-related TOF PID (0: no, 1: yes, -1: auto)"}; // Operation and minimisation criteria - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; - Configurable doQA{"doQA", true, "create QA histos"}; - Configurable doNSigmas{"doNSigmas", false, "calculate TOF N-sigma"}; - Configurable doQANSigma{"doQANSigma", true, "create QA of Nsigma histos"}; + struct : ConfigurableGroup { + Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; + Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; + + Configurable correctELossInclination{"correctELossInclination", false, "factor out inclination when doing effective e-loss correction (0: no, 1: yes)"}; + Configurable numberOfStepsFirstStage{"numberOfStepsFirstStage", 500, "Max number of alpha rotations to attempt in first stage"}; + Configurable numberOfStepsSecondStage{"numberOfStepsSecondStage", 500, "Max number of steps rotations to attempt in second stage"}; + Configurable stepSizeFirstStage{"stepSizeFirstStage", 2.0f, "Max number of alpha rotations to attempt in first stage"}; + Configurable firstApproximationThreshold{"firstApproximationThreshold", 4.0f, "be satisfied if first approach to TOF radius is OK within this threshold (cm)"}; + + // regulate e-loss calculation to save CPU + Configurable maxPionMomentumForEloss{"maxPionMomentumForEloss", 1.5f, "above this momentum, do fast analytical TOF calculation for pions"}; + Configurable maxKaonMomentumForEloss{"maxKaonMomentumForEloss", 2.0f, "above this momentum, do fast analytical TOF calculation for kaons"}; + Configurable maxProtonMomentumForEloss{"maxProtonMomentumForEloss", 2.5f, "above this momentum, do fast analytical TOF calculation for protons"}; + + Configurable rejectKaonMomentumForEloss{"rejectKaonMomentumForEloss", 0.2f, "below this momentum, reject kaon hypothesis (won't reach TOF)"}; + Configurable rejectProtonMomentumForEloss{"rejectProtonMomentumForEloss", 0.2f, "below this momentum, reject proton hypothesis (won't reach TOF)"}; + + Configurable tpcNsigmaThreshold{"tpcNsigmaThreshold", 6.0f, "require TPC compatibility to attempt eloss propagation (otherwise, don't calculate)"}; + } propagationConfiguration; + + Configurable doQA{"doQA", false, "create QA histos"}; + Configurable doNSigmas{"doNSigmas", true, "calculate TOF N-sigma"}; + Configurable doQANSigma{"doQANSigma", false, "create QA of Nsigma histos"}; // configurables related to V0s struct : ConfigurableGroup { @@ -121,28 +147,34 @@ struct strangenesstofpid { } cascadeGroup; // CCDB options - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable nSigmaPath{"nSigmaPath", "Users/d/ddobrigk/stratof", "Path of information for n-sigma calculation"}; - Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + // CCDB options + struct : ConfigurableGroup { + std::string prefix = "ccdb"; + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable nSigmaPath{"nSigmaPath", "Users/d/ddobrigk/stratof", "Path of information for n-sigma calculation"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + } ccdbConfigurations; // manual Configurable useCustomRunNumber{"useCustomRunNumber", false, "Use custom timestamp"}; Configurable manualRunNumber{"manualRunNumber", 544122, "manual run number if no collisions saved"}; + ConfigurableAxis axisPosition{"axisPosition", {400, -400.f, +400.f}, "position (cm)"}; ConfigurableAxis axisEta{"axisEta", {20, -1.0f, +1.0f}, "#eta"}; ConfigurableAxis axisDeltaTime{"axisDeltaTime", {2000, -1000.0f, +1000.0f}, "delta-time (ps)"}; - ConfigurableAxis axisTime{"axisTime", {200, 10000.0f, +20000.0f}, "T (ps)"}; + ConfigurableAxis axisTime{"axisTime", {400, 10000.0f, +50000.0f}, "T (ps)"}; ConfigurableAxis axisNSigma{"axisNSigma", {200, -10.0f, +10.0f}, "N(#sigma)"}; - ConfigurableAxis axisExpectedOverMeasured{"axisExpectedOverMeasured", {200, 0.9f, 2.9f}, "T_{exp}/T_{meas}"}; + ConfigurableAxis axisRatioMethods{"axisRatioMethods", {400, 0.9f, 1.9f}, "T_{method 1}/T_{method 0}"}; + ConfigurableAxis axisSnp{"axisSnp", {220, -1.1f, 1.1f}, "snp"}; // master p axis ConfigurableAxis axisP{"axisP", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "p_{T} (GeV/c)"}; // for zooming in at low values only (e-loss studies and effective correction) - ConfigurableAxis axisSmallP{"axisSmallP", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisSmallP{"axisSmallP", {250, 0.0f, 2.5f}, "p_{T} (GeV/c)"}; // for n-sigma calibration bool nSigmaCalibLoaded; @@ -288,20 +320,153 @@ struct strangenesstofpid { // Detector segmentation loop float segmentAngle = 20.0f / 180.0f * TMath::Pi(); float theta = static_cast(iSeg) * 20.0f / 180.0f * TMath::Pi(); - float halfWidth = tofPosition * TMath::Tan(0.5f * segmentAngle); - float x1 = TMath::Cos(theta) * (-halfWidth) + TMath::Sin(theta) * tofPosition; - float y1 = -TMath::Sin(theta) * (-halfWidth) + TMath::Cos(theta) * tofPosition; - float x2 = TMath::Cos(theta) * (+halfWidth) + TMath::Sin(theta) * tofPosition; - float y2 = -TMath::Sin(theta) * (+halfWidth) + TMath::Cos(theta) * tofPosition; + float halfWidth = propagationConfiguration.tofPosition * TMath::Tan(0.5f * segmentAngle); + float x1 = TMath::Cos(theta) * (-halfWidth) + TMath::Sin(theta) * propagationConfiguration.tofPosition; + float y1 = -TMath::Sin(theta) * (-halfWidth) + TMath::Cos(theta) * propagationConfiguration.tofPosition; + float x2 = TMath::Cos(theta) * (+halfWidth) + TMath::Sin(theta) * propagationConfiguration.tofPosition; + float y2 = -TMath::Sin(theta) * (+halfWidth) + TMath::Cos(theta) * propagationConfiguration.tofPosition; float thisLength = trackLengthToSegment(track, x1, y1, x2, y2, magneticField); - if (thisLength < length && thisLength > 0) + if (thisLength < length && thisLength > 0) { length = thisLength; + } } if (length > 1e+5) length = -100; // force negative to avoid misunderstandings return length; } + /// O2 Propagator + TrackLTIntegral approach helpers + + /// function to calculate segmented (truncated) radius based on a certain x, y position + float segmentedRadius(float x, float y) + { + float atAngle = std::atan2(y, x); + float roundedAngle = TMath::Pi() / 9; // 18 segments = use 9 here + float angleSegmentAxis = 0.5f * roundedAngle + roundedAngle * static_cast(std::floor(atAngle / roundedAngle)); + float xSegmentAxis = TMath::Cos(angleSegmentAxis); + float ySegmentAxis = TMath::Sin(angleSegmentAxis); + return xSegmentAxis * x + ySegmentAxis * y; // inner product + } + + /// function to calculate track length of this track up to a certain segmented detector + /// \param track the input track + /// \param time returned time (with PID given by track PID) + void calculateTOF(o2::track::TrackPar track, float& time) + { + time = -1e+6; + + if (track.getPID() == o2::track::PID::Proton && track.getP() < propagationConfiguration.rejectProtonMomentumForEloss.value) { + return; // don't attempt to calculate below-threshold protons (will stop anyway) + } + if (track.getPID() == o2::track::PID::Kaon && track.getP() < propagationConfiguration.rejectKaonMomentumForEloss.value) { + return; // don't attempt to calculate below-threshold kaons (will stop anyway) + } + + o2::track::TrackLTIntegral ltIntegral; + + static constexpr float MAX_SIN_PHI = 0.85f; + static constexpr float MAX_STEP = 2.0f; + static constexpr float MAX_STEP_FINAL_STAGE = 0.5f; + static constexpr float MAX_FINAL_X = 450.0f; // maximum extra X on top of TOF X for correcting value + + //____________________________________________________________ + // stage 1: propagate to TOF-inscribed circle at tofPosition + + // define standard variables + std::array xyz; + std::array pxpypz; + track.getXYZGlo(xyz); + float segmentedRstart = segmentedRadius(xyz[0], xyz[1]); + + bool firstPropag = true; + for (int iRot = 0; iRot < propagationConfiguration.numberOfStepsFirstStage.value; iRot++) { + track.rotateParam(track.getPhi()); // start rotated + float currentX = track.getX(); + float tofX = currentX; + track.getXatLabR(propagationConfiguration.tofPosition, tofX, d_bz, o2::track::DirOutward); + if (std::abs(tofX - currentX) < propagationConfiguration.firstApproximationThreshold.value) { + // signal conclusion + if (calculationMethod.value == 2) { + histos.fill(HIST("hInitialPropagationSteps"), iRot); // store number of steps + } + break; + } + float nextX = std::min(currentX + propagationConfiguration.stepSizeFirstStage.value, tofX); + firstPropag = o2::base::Propagator::Instance()->propagateToX(track, nextX, d_bz, MAX_SIN_PHI, MAX_STEP, o2::base::Propagator::MatCorrType::USEMatCorrLUT, <Integral); + } + + // mark start position of next step + track.getXYZGlo(xyz); + float snp = track.getSnp(); + float segmentedR = segmentedRadius(xyz[0], xyz[1]); + float segmentedRintermediate = segmentedR; + float currentTime = ltIntegral.getTOF(track.getPID()); + if (calculationMethod.value == 2) { + histos.fill(HIST("hSegRadiusFirstPropagVsStart"), segmentedRstart, segmentedR); // for debugging purposes + histos.fill(HIST("hSnp"), track.getSnp()); // for debugging purposes + histos.fill(HIST("hTOFPosition"), xyz[0], xyz[1]); // for debugging purposes + histos.fill(HIST("hSegRadius"), segmentedR); // for debugging purposes + if (!firstPropag) { + histos.fill(HIST("hTOFPositionFirstPropagFail"), xyz[0], xyz[1]); // for debugging purposes + histos.fill(HIST("hSegRadiusFirstPropagFail"), segmentedR); // for debugging purposes + histos.fill(HIST("hSnpFirstPropagFail"), track.getSnp()); // for debugging purposes + } + } + + // correct for TOF segmentation + bool trackOKextra = true; + float trackXextra = track.getX(); + int propagationSteps = 0; + int maxPropagationSteps = propagationConfiguration.numberOfStepsSecondStage.value; + while ((trackXextra < MAX_FINAL_X) && (propagationSteps < maxPropagationSteps)) { + // continue with alpha aligned with pT + track.getPxPyPzGlo(pxpypz); + track.rotateParam(std::atan2(pxpypz[1], pxpypz[0])); + trackXextra = track.getX() + MAX_STEP_FINAL_STAGE; + trackOKextra = o2::base::Propagator::Instance()->propagateToX(track, trackXextra, d_bz, MAX_SIN_PHI, MAX_STEP, o2::base::Propagator::MatCorrType::USEMatCorrLUT, <Integral); + if (!trackOKextra) { + if (calculationMethod.value == 2) { + track.getXYZGlo(xyz); + histos.fill(HIST("hTOFPositionStopped"), xyz[0], xyz[1]); // for debugging purposes + histos.fill(HIST("hSnpStopped"), snp); // for debugging purposes + histos.fill(HIST("hSegRadiusStopped"), segmentedRadius(xyz[0], xyz[1])); // for debugging purposes + histos.fill(HIST("hSegRadiusStoppedVsFirstPropag"), segmentedRintermediate, segmentedRadius(xyz[0], xyz[1])); // for debugging purposes + } + time = -1e+6; + return; // propagation failed, skip, won't look reasonable + } + + // re-evaluate - did we cross? if yes break + float previousX = xyz[0], previousY = xyz[1]; + track.getXYZGlo(xyz); + if (segmentedRadius(xyz[0], xyz[1]) > propagationConfiguration.tofPosition) { + // crossed boundary -> do proportional scaling with how much we actually crossed the boundary + float segmentedRFinal = segmentedRadius(xyz[0], xyz[1]); + float timeFinal = ltIntegral.getTOF(track.getPID()); + float fraction = (propagationConfiguration.tofPosition - segmentedR) / (segmentedRFinal - segmentedR + 1e-6); // proportional fraction + time = currentTime + (timeFinal - currentTime) * fraction; + if (calculationMethod.value == 2) { + histos.fill(HIST("hTOFPositionFinal"), previousX + fraction * (xyz[0] - previousX), previousY + fraction * (xyz[1] - previousY)); // for debugging purposes + histos.fill(HIST("hSegRadiusFinal"), segmentedRadius(previousX + fraction * (xyz[0] - previousX), previousY + fraction * (xyz[1] - previousY))); // for debugging purposes + histos.fill(HIST("hSnpFinal"), track.getSnp()); // for debugging purposes + histos.fill(HIST("hSegRadiusFinalVsFirstPropag"), segmentedRintermediate, segmentedRadius(previousX + fraction * (xyz[0] - previousX), previousY + fraction * (xyz[1] - previousY))); // for debugging purposes + histos.fill(HIST("hRefinedPropagationSteps"), propagationSteps, 1.0f); // for debugging purposes + } + return; // get out of the entire function and return (don't just break) + } + + // prepare for next step by setting current position and desired variables + segmentedR = segmentedRadius(xyz[0], xyz[1]); + currentTime = ltIntegral.getTOF(track.getPID()); + propagationSteps++; + } + if (calculationMethod.value == 2) { + histos.fill(HIST("hRefinedPropagationSteps"), propagationSteps, 0.0f); // for debugging purposes + track.getXYZGlo(xyz); + histos.fill(HIST("hSegRadiusGotLost"), segmentedRadius(xyz[0], xyz[1])); // for debugging purposes + } + } + void init(InitContext& initContext) { if (calculateV0s.value < 0) { @@ -341,7 +506,7 @@ struct strangenesstofpid { maxSnp = 0.85f; // could be changed later maxStep = 2.00f; // could be changed later - ccdb->setURL(ccdburl); + ccdb->setURL(ccdbConfigurations.ccdburl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); @@ -351,12 +516,6 @@ struct strangenesstofpid { // measured vs expected total time QA if (doQA) { - // plots for effective eloss corrections - Lambda case - histos.add("h2dProtonMeasuredVsExpected", "h2dProtonMeasuredVsExpected", {HistType::kTH3F, {axisSmallP, axisExpectedOverMeasured, axisEta}}); - histos.add("h2dPionMeasuredVsExpected", "h2dPionMeasuredVsExpected", {HistType::kTH3F, {axisSmallP, axisExpectedOverMeasured, axisEta}}); - - histos.add("hArcDebug", "hArcDebug", kTH2F, {axisP, {50, -5.0f, 10.0f}}); - // standard deltaTime values if (calculateV0s.value > 0) { histos.add("h2dDeltaTimePositiveLambdaPi", "h2dDeltaTimePositiveLambdaPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); @@ -407,6 +566,93 @@ struct strangenesstofpid { // delta lambda decay time histos.add("h2dLambdaDeltaDecayTime", "h2dLambdaDeltaDecayTime", {HistType::kTH2F, {axisP, axisDeltaTime}}); } + + if (calculationMethod.value == 2) { + //_____________________________________________________________________ + // special mode in which comparison histograms are required + + //_____________________________________________________________________ + // histograms for debugging modes 0 vs 1 + // encoded success rates in each hypothesis and method vs prong p + histos.add("h2dSucessRatePion", "h2dSucessRatePion", kTH2F, {axisSmallP, {4, -0.5f, 3.5f}}); + histos.add("h2dSucessRateKaon", "h2dSucessRateKaon", kTH2F, {axisSmallP, {4, -0.5f, 3.5f}}); + histos.add("h2dSucessRateProton", "h2dSucessRateProton", kTH2F, {axisSmallP, {4, -0.5f, 3.5f}}); + + histos.add("hInitialPropagationSteps", "hInitialPropagationSteps", kTH1F, {{500, -0.5f, 499.5f}}); + histos.add("hRefinedPropagationSteps", "hRefinedPropagationSteps", kTH2F, {{1000, -0.5f, 999.5f}, {2, -0.5f, 1.5f}}); + + // base ArcDebug: comparison between times of arrival in different methods + histos.add("hArcDebug", "hArcDebug", kTH2F, {axisTime, axisTime}); + + // Position of TrackLTIntegral method: intermediate (getXatLabR) and final (reach segmented detector) + histos.add("hTOFPosition", "hTOFPosition", kTH2F, {axisPosition, axisPosition}); + histos.add("hTOFPositionFirstPropagFail", "hTOFPositionFirstPropagFail", kTH2F, {axisPosition, axisPosition}); + histos.add("hTOFPositionFinal", "hTOFPositionFinal", kTH2F, {axisPosition, axisPosition}); + histos.add("hTOFPositionGetXAtLabFail", "hTOFPositionGetXAtLabFail", kTH2F, {axisPosition, axisPosition}); + histos.add("hTOFPositionStopped", "hTOFPositionStopped", kTH2F, {axisPosition, axisPosition}); + + // Snp cross-check + histos.add("hSnp", "hSnp", kTH1F, {axisSnp}); + histos.add("hSnpFirstPropagFail", "hSnpFirstPropagFail", kTH1F, {axisSnp}); + histos.add("hSnpFinal", "hSnpFinal", kTH1F, {axisSnp}); + histos.add("hSnpGetXAtLabFail", "hSnpGetXAtLabFail", kTH1F, {axisSnp}); + histos.add("hSnpStopped", "hSnpStopped", kTH1F, {axisSnp}); + + // segmented radius: positions + histos.add("hSegRadius", "hSegRadius", kTH1F, {{400, 0.0f, 400.0f}}); + histos.add("hSegRadiusFirstPropagFail", "hSegRadiusFirstPropagFail", kTH1F, {{400, 0.0f, 400.0f}}); + histos.add("hSegRadiusFinal", "hSegRadiusFinal", kTH1F, {{400, 0.0f, 400.0f}}); + histos.add("hSegRadiusStopped", "hSegRadiusStopped", kTH1F, {{400, 0.0f, 400.0f}}); + histos.add("hSegRadiusGotLost", "hSegRadiusGotLost", kTH1F, {{400, 0.0f, 400.0f}}); + + histos.add("hSegRadiusFirstPropagVsStart", "hSegRadiusFirstPropagVsStart", kTH2F, {{400, 0.0f, 400.0f}, {400, 0.0f, 400.0f}}); + histos.add("hSegRadiusStoppedVsFirstPropag", "hSegRadiusStoppedVsFirstPropag", kTH2F, {{400, 0.0f, 400.0f}, {400, 0.0f, 400.0f}}); + histos.add("hSegRadiusFinalVsFirstPropag", "hSegRadiusFinalVsFirstPropag", kTH2F, {{400, 0.0f, 400.0f}, {400, 0.0f, 400.0f}}); + + // Delta-times of each method for the various species + histos.add("hDeltaTimeMethodsVsP_posLaPr", "hDeltaTimeMethodsVsP_posLaPr", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_posLaPi", "hDeltaTimeMethodsVsP_posLaPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_posK0Pi", "hDeltaTimeMethodsVsP_posK0Pi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negLaPr", "hDeltaTimeMethodsVsP_negLaPr", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negLaPi", "hDeltaTimeMethodsVsP_negLaPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negK0Pi", "hDeltaTimeMethodsVsP_negK0Pi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + + histos.add("hDeltaTimeMethodsVsP_posXiPi", "hDeltaTimeMethodsVsP_posXiPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_posXiPr", "hDeltaTimeMethodsVsP_posXiPr", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negXiPi", "hDeltaTimeMethodsVsP_negXiPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negXiPr", "hDeltaTimeMethodsVsP_negXiPr", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_bachXiPi", "hDeltaTimeMethodsVsP_bachXiPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + + histos.add("hDeltaTimeMethodsVsP_posOmPi", "hDeltaTimeMethodsVsP_posOmPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_posOmPr", "hDeltaTimeMethodsVsP_posOmPr", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negOmPi", "hDeltaTimeMethodsVsP_negOmPi", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_negOmPr", "hDeltaTimeMethodsVsP_negOmPr", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + histos.add("hDeltaTimeMethodsVsP_bachOmKa", "hDeltaTimeMethodsVsP_bachOmKa", kTH3F, {axisSmallP, axisEta, axisDeltaTime}); + + histos.add("hRatioTimeMethodsVsP_posLaPr", "hRatioTimeMethodsVsP_posLaPr", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_posLaPi", "hRatioTimeMethodsVsP_posLaPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_posK0Pi", "hRatioTimeMethodsVsP_posK0Pi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negLaPr", "hRatioTimeMethodsVsP_negLaPr", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negLaPi", "hRatioTimeMethodsVsP_negLaPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negK0Pi", "hRatioTimeMethodsVsP_negK0Pi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + + histos.add("hRatioTimeMethodsVsP_posXiPi", "hRatioTimeMethodsVsP_posXiPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_posXiPr", "hRatioTimeMethodsVsP_posXiPr", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negXiPi", "hRatioTimeMethodsVsP_negXiPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negXiPr", "hRatioTimeMethodsVsP_negXiPr", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_bachXiPi", "hRatioTimeMethodsVsP_bachXiPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + + histos.add("hRatioTimeMethodsVsP_posOmPi", "hRatioTimeMethodsVsP_posOmPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_posOmPr", "hRatioTimeMethodsVsP_posOmPr", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negOmPi", "hRatioTimeMethodsVsP_negOmPi", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_negOmPr", "hRatioTimeMethodsVsP_negOmPr", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + histos.add("hRatioTimeMethodsVsP_bachOmKa", "hRatioTimeMethodsVsP_bachOmKa", kTH3F, {axisSmallP, axisEta, axisRatioMethods}); + } + + // list memory consumption at start if running in modes with more output + if (calculationMethod.value == 2 || doQA) { + histos.print(); + } } void initCCDB(int runNumber) @@ -416,19 +662,19 @@ struct strangenesstofpid { } // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; + if (propagationConfiguration.d_bz_input > -990) { + d_bz = propagationConfiguration.d_bz_input; o2::parameters::GRPMagField grpmag; if (fabs(d_bz) > 1e-5) { grpmag.setL3Current(30000.f / (d_bz / 5.0f)); } o2::base::Propagator::initFieldFromGRP(&grpmag); - mVtx = ccdb->getForRun(mVtxPath, runNumber); + mVtx = ccdb->getForRun(ccdbConfigurations.mVtxPath, runNumber); mRunNumber = runNumber; return; } - o2::parameters::GRPObject* grpo = ccdb->getForRun(grpPath, runNumber); + o2::parameters::GRPObject* grpo = ccdb->getForRun(ccdbConfigurations.grpPath, runNumber); o2::parameters::GRPMagField* grpmag = 0x0; if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); @@ -436,20 +682,20 @@ struct strangenesstofpid { d_bz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; } else { - grpmag = ccdb->getForRun(grpmagPath, runNumber); + grpmag = ccdb->getForRun(ccdbConfigurations.grpmagPath, runNumber); if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for run " << runNumber; + LOG(fatal) << "Got nullptr from CCDB for path " << ccdbConfigurations.grpmagPath << " of object GRPMagField and " << ccdbConfigurations.grpPath << " of object GRPObject for run " << runNumber; } o2::base::Propagator::initFieldFromGRP(grpmag); // Fetch magnetic field from ccdb for current collision d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - mVtx = ccdb->getForRun(mVtxPath, runNumber); + mVtx = ccdb->getForRun(ccdbConfigurations.mVtxPath, runNumber); LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; } // if TOF Nsigma desired if (doNSigmas) { - nSigmaCalibObjects = ccdb->getForRun(nSigmaPath, runNumber); + nSigmaCalibObjects = ccdb->getForRun(ccdbConfigurations.nSigmaPath, runNumber); if (nSigmaCalibObjects) { LOGF(info, "loaded TList with this many objects: %i", nSigmaCalibObjects->GetEntries()); nSigmaCalibLoaded = true; // made it thus far, mark loaded @@ -520,6 +766,16 @@ struct strangenesstofpid { } } } + + if (calculationMethod.value > 0 && !lut) { + // setMatLUT only after magfield has been initalized + // (setMatLUT has implicit and problematic init field call if not) + LOG(info) << "Loading full (all-radius) material look-up table for run number: " << runNumber; + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->getForRun(ccdbConfigurations.lutPath, runNumber)); + o2::base::Propagator::Instance()->setMatLUT(lut); + o2::base::Propagator::Instance()->setTGeoFallBackAllowed(false); + LOG(info) << "Material look-up table loaded!"; + } mRunNumber = runNumber; } @@ -533,7 +789,7 @@ struct strangenesstofpid { // templatized process function for symmetric operation in derived and original AO2D template - void processV0Candidate(TCollision const& collision, TV0 const& v0, TTrack const& pTra, TTrack const& nTra) + void processV0Candidate(TCollision const& collision, TV0 const& v0, TTrack const& pTra, TTrack const& nTra, int v0pdg) { // time of V0 segment float lengthV0 = std::hypot(v0.x() - collision.getX(), v0.y() - collision.getY(), v0.z() - collision.getZ()); @@ -543,8 +799,12 @@ struct strangenesstofpid { float timeLambda = lengthV0 / velocityLambda; // in picoseconds // initialize from V0 position and momenta - o2::track::TrackPar posTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxpos(), v0.pypos(), v0.pzpos()}, +1); - o2::track::TrackPar negTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxneg(), v0.pyneg(), v0.pzneg()}, -1); + o2::track::TrackPar posTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxpos(), v0.pypos(), v0.pzpos()}, +1, false); + o2::track::TrackPar negTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxneg(), v0.pyneg(), v0.pzneg()}, -1, false); + + // at minimum + float positiveP = std::hypot(v0.pxpos(), v0.pypos(), v0.pzpos()); + float negativeP = std::hypot(v0.pxneg(), v0.pyneg(), v0.pzneg()); float deltaTimePositiveLambdaPi = o2::aod::v0data::kNoTOFValue; float deltaTimeNegativeLambdaPi = o2::aod::v0data::kNoTOFValue; @@ -560,24 +820,123 @@ struct strangenesstofpid { float nSigmaPositiveK0ShortPi = o2::aod::v0data::kNoTOFValue; float nSigmaNegativeK0ShortPi = o2::aod::v0data::kNoTOFValue; + float timePositivePr = o2::aod::v0data::kNoTOFValue; + float timePositivePi = o2::aod::v0data::kNoTOFValue; + float timeNegativePr = o2::aod::v0data::kNoTOFValue; + float timeNegativePi = o2::aod::v0data::kNoTOFValue; + + float timePositivePr_Method0 = o2::aod::v0data::kNoTOFValue; + float timePositivePi_Method0 = o2::aod::v0data::kNoTOFValue; + float timeNegativePr_Method0 = o2::aod::v0data::kNoTOFValue; + float timeNegativePi_Method0 = o2::aod::v0data::kNoTOFValue; + + float timePositivePr_Method1 = o2::aod::v0data::kNoTOFValue; + float timePositivePi_Method1 = o2::aod::v0data::kNoTOFValue; + float timeNegativePr_Method1 = o2::aod::v0data::kNoTOFValue; + float timeNegativePi_Method1 = o2::aod::v0data::kNoTOFValue; + float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); - float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? - float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? - float timePositivePr = lengthPositive / velocityPositivePr; - float timePositivePi = lengthPositive / velocityPositivePi; - float timeNegativePr = lengthNegative / velocityNegativePr; - float timeNegativePi = lengthNegative / velocityNegativePi; + if (pTra.hasTOF() && pTra.hasITS()) { + float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? + if (lengthPositive > 0) { + timePositivePr_Method0 = lengthPositive / velocityPositivePr; + timePositivePi_Method0 = lengthPositive / velocityPositivePi; + } + } + if (nTra.hasTOF() && nTra.hasITS()) { + float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? + if (lengthNegative > 0) { + timeNegativePr_Method0 = lengthNegative / velocityNegativePr; + timeNegativePi_Method0 = lengthNegative / velocityNegativePi; + } + } + + if (calculationMethod.value > 0) { + // method to calculate the time and length via Propagator TrackLTIntegral + if (pTra.hasTOF() && pTra.hasITS()) { // calculate if signal present, otherwise skip + if (posTrack.getP() < propagationConfiguration.maxProtonMomentumForEloss.value && std::abs(pTra.tpcNSigmaPr()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar posTrackAsProton(posTrack); + posTrackAsProton.setPID(o2::track::PID::Proton); + calculateTOF(posTrackAsProton, timePositivePr_Method1); + } else { + timePositivePr_Method1 = timePositivePr_Method0; + } + if (posTrack.getP() < propagationConfiguration.maxPionMomentumForEloss.value && std::abs(pTra.tpcNSigmaPi()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar posTrackAsPion(posTrack); + posTrackAsPion.setPID(o2::track::PID::Pion); + calculateTOF(posTrackAsPion, timePositivePi_Method1); + } else { + timePositivePi_Method1 = timePositivePi_Method0; + } + } + if (nTra.hasTOF() && nTra.hasITS()) { // calculate if signal present, otherwise skip + if (negTrack.getP() < propagationConfiguration.maxProtonMomentumForEloss.value && std::abs(nTra.tpcNSigmaPr()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar negTrackAsProton(negTrack); + negTrackAsProton.setPID(o2::track::PID::Proton); + calculateTOF(negTrackAsProton, timeNegativePr_Method1); + } else { + timeNegativePr_Method1 = timeNegativePr_Method0; + } + + if (negTrack.getP() < propagationConfiguration.maxPionMomentumForEloss.value && std::abs(nTra.tpcNSigmaPi()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar negTrackAsPion(negTrack); + negTrackAsPion.setPID(o2::track::PID::Pion); + calculateTOF(negTrackAsPion, timeNegativePi_Method1); + } else { + timeNegativePi_Method1 = timeNegativePi_Method0; + } + } + } + + // assign values to be used in main calculation + if (calculationMethod.value == 0) { + timePositivePr = timePositivePr_Method0; + timePositivePi = timePositivePi_Method0; + timeNegativePr = timeNegativePr_Method0; + timeNegativePi = timeNegativePi_Method0; + } else { + timePositivePr = timePositivePr_Method1; + timePositivePi = timePositivePi_Method1; + timeNegativePr = timeNegativePr_Method1; + timeNegativePi = timeNegativePi_Method1; + } + + if (calculationMethod.value == 2) { + // do analysis of successes and failures + bool positiveSuccessMethod0Pr = std::abs(timePositivePr_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool negativeSuccessMethod0Pr = std::abs(timeNegativePr_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool positiveSuccessMethod1Pr = std::abs(timePositivePr_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool negativeSuccessMethod1Pr = std::abs(timeNegativePr_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool positiveSuccessMethod0Pi = std::abs(timePositivePi_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool negativeSuccessMethod0Pi = std::abs(timeNegativePi_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool positiveSuccessMethod1Pi = std::abs(timePositivePi_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + bool negativeSuccessMethod1Pi = std::abs(timeNegativePi_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon; + + int encodedPositiveSuccessPi = positiveSuccessMethod0Pi + 2 * positiveSuccessMethod1Pi; + int encodedPositiveSuccessPr = positiveSuccessMethod0Pr + 2 * positiveSuccessMethod1Pr; + int encodedNegativeSuccessPi = negativeSuccessMethod0Pi + 2 * negativeSuccessMethod1Pi; + int encodedNegativeSuccessPr = negativeSuccessMethod0Pr + 2 * negativeSuccessMethod1Pr; + + if (pTra.hasTOF()) { + histos.fill(HIST("h2dSucessRateProton"), positiveP, encodedPositiveSuccessPr); + histos.fill(HIST("h2dSucessRatePion"), positiveP, encodedPositiveSuccessPi); + } + if (nTra.hasTOF()) { + histos.fill(HIST("h2dSucessRateProton"), negativeP, encodedNegativeSuccessPr); + histos.fill(HIST("h2dSucessRatePion"), negativeP, encodedNegativeSuccessPi); + } + } - if (pTra.hasTOF() && lengthPositive > 0) { + if (pTra.hasTOF() && pTra.hasITS() && timePositivePr > 0) { deltaTimePositiveLambdaPr = (pTra.tofSignal() - pTra.tofEvTime()) - (timeLambda + timePositivePr); deltaTimePositiveLambdaPi = (pTra.tofSignal() - pTra.tofEvTime()) - (timeLambda + timePositivePi); deltaTimePositiveK0ShortPi = (pTra.tofSignal() - pTra.tofEvTime()) - (timeK0Short + timePositivePi); } - if (nTra.hasTOF() && lengthNegative > 0) { + if (nTra.hasTOF() && nTra.hasITS() && timeNegativePr > 0) { deltaTimeNegativeLambdaPr = (nTra.tofSignal() - nTra.tofEvTime()) - (timeLambda + timeNegativePr); deltaTimeNegativeLambdaPi = (nTra.tofSignal() - nTra.tofEvTime()) - (timeLambda + timeNegativePi); deltaTimeNegativeK0ShortPi = (nTra.tofSignal() - nTra.tofEvTime()) - (timeK0Short + timeNegativePi); @@ -586,12 +945,12 @@ struct strangenesstofpid { if (doQA) { // calculate and pack properties for QA purposes int posProperties = 0; - if (lengthPositive > 0) + if (timePositivePr > 0) posProperties = posProperties | (static_cast(1) << kLength); if (pTra.hasTOF()) posProperties = posProperties | (static_cast(1) << kHasTOF); int negProperties = 0; - if (lengthNegative > 0) + if (timeNegativePr > 0) negProperties = negProperties | (static_cast(1) << kLength); if (nTra.hasTOF()) negProperties = negProperties | (static_cast(1) << kHasTOF); @@ -603,7 +962,7 @@ struct strangenesstofpid { float deltaDecayTimeLambda = -10e+4; float deltaDecayTimeAntiLambda = -10e+4; float deltaDecayTimeK0Short = -10e+4; - if (nTra.hasTOF() && pTra.hasTOF() > 0 && lengthPositive > 0 && lengthNegative > 0) { // does not depend on event time + if (nTra.hasTOF() && pTra.hasTOF() && timePositivePr > 0 && timeNegativePr > 0) { // does not depend on event time deltaDecayTimeLambda = (pTra.tofSignal() - timePositivePr) - (nTra.tofSignal() - timeNegativePi); deltaDecayTimeAntiLambda = (pTra.tofSignal() - timePositivePi) - (nTra.tofSignal() - timeNegativePr); deltaDecayTimeK0Short = (pTra.tofSignal() - timePositivePi) - (nTra.tofSignal() - timeNegativePi); @@ -617,11 +976,8 @@ struct strangenesstofpid { float decayTimeK0Short = 0.5f * ((pTra.tofSignal() - timePositivePi) + (nTra.tofSignal() - timeNegativePi)) - evTimeMean; float betaLambda = o2::aod::cascdata::kNoTOFValue; - ; float betaAntiLambda = o2::aod::cascdata::kNoTOFValue; - ; float betaK0Short = o2::aod::cascdata::kNoTOFValue; - ; if (nTra.hasTOF() && pTra.hasTOF()) { betaLambda = (lengthV0 / decayTimeLambda) / 0.0299792458; @@ -659,92 +1015,107 @@ struct strangenesstofpid { nSigmaPositiveK0ShortPi, nSigmaNegativeK0ShortPi); } - float positiveP = std::hypot(v0.pxpos(), v0.pypos(), v0.pzpos()); - float negativeP = std::hypot(v0.pxneg(), v0.pyneg(), v0.pzneg()); - if (doQA) { - if (pTra.hasTOF()) { + // length factor due to eta (to offset e-loss) + float positiveCosine = 1.0f / sqrt(1.0f + posTrack.getTgl() * posTrack.getTgl()); + float negativeCosine = 1.0f / sqrt(1.0f + negTrack.getTgl() * negTrack.getTgl()); + if (propagationConfiguration.correctELossInclination.value == false) { + negativeCosine = positiveCosine = 1.0f; + } + + if (pTra.hasTOF() && pTra.hasITS()) { if (v0.v0cosPA() > v0Group.qaCosPA && v0.dcaV0daughters() < v0Group.qaDCADau) { - if (std::abs(v0.mLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + if (std::abs(v0.mLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && ((v0pdg == 0) || (v0pdg == 3122))) { histos.fill(HIST("h2dDeltaTimePositiveLambdaPr"), v0.p(), v0.eta(), deltaTimePositiveLambdaPr); - histos.fill(HIST("h2dProtonMeasuredVsExpected"), - (timeLambda + timePositivePr) / (pTra.tofSignal() - pTra.tofEvTime()), - positiveP, v0.positiveeta()); + if (calculationMethod.value == 2 && std::abs(timePositivePr_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon && std::abs(timePositivePr_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posLaPr"), positiveP, v0.positiveeta(), (timePositivePr_Method0 - timePositivePr_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posLaPr"), positiveP, v0.positiveeta(), (timePositivePr_Method1 / timePositivePr_Method0) * positiveCosine); + } if (doQANSigma) histos.fill(HIST("h2dNSigmaPositiveLambdaPr"), v0.p(), nSigmaPositiveLambdaPr); } - if (std::abs(v0.mAntiLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma) { + if (std::abs(v0.mAntiLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && ((v0pdg == 0) || (v0pdg == -3122))) { histos.fill(HIST("h2dDeltaTimePositiveLambdaPi"), v0.p(), v0.eta(), deltaTimePositiveLambdaPi); + if (calculationMethod.value == 2 && std::abs(timePositivePi_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon && std::abs(timePositivePi_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posLaPi"), positiveP, v0.positiveeta(), (timePositivePi_Method0 - timePositivePi_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posLaPi"), positiveP, v0.positiveeta(), (timePositivePi_Method1 / timePositivePi_Method0) * positiveCosine); + } if (doQANSigma) histos.fill(HIST("h2dNSigmaPositiveLambdaPi"), v0.p(), nSigmaPositiveLambdaPi); } - if (std::abs(v0.mK0Short() - 0.497) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + if (std::abs(v0.mK0Short() - 0.497) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && ((v0pdg == 0) || (v0pdg == 310))) { histos.fill(HIST("h2dDeltaTimePositiveK0ShortPi"), v0.p(), v0.eta(), deltaTimePositiveK0ShortPi); + if (calculationMethod.value == 2 && std::abs(timePositivePi_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon && std::abs(timePositivePi_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posK0Pi"), positiveP, v0.positiveeta(), (timePositivePi_Method0 - timePositivePi_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posK0Pi"), positiveP, v0.positiveeta(), (timePositivePi_Method1 / timePositivePi_Method0) * positiveCosine); + } if (doQANSigma) histos.fill(HIST("h2dNSigmaPositiveK0ShortPi"), v0.p(), nSigmaPositiveK0ShortPi); } } } - if (nTra.hasTOF()) { + if (nTra.hasTOF() && nTra.hasITS()) { if (v0.v0cosPA() > v0Group.qaCosPA && v0.dcaV0daughters() < v0Group.qaDCADau) { - if (std::abs(v0.mLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + if (std::abs(v0.mLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && ((v0pdg == 0) || (v0pdg == 3122))) { histos.fill(HIST("h2dDeltaTimeNegativeLambdaPi"), v0.p(), v0.eta(), deltaTimeNegativeLambdaPi); - histos.fill(HIST("h2dPionMeasuredVsExpected"), - (timeLambda + timeNegativePi) / (nTra.tofSignal() - nTra.tofEvTime()), - negativeP, v0.negativeeta()); + if (calculationMethod.value == 2 && std::abs(timeNegativePi_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon && std::abs(timeNegativePi_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negLaPi"), negativeP, v0.negativeeta(), (timeNegativePi_Method0 - timeNegativePi_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negLaPi"), negativeP, v0.negativeeta(), (timeNegativePi_Method1 / timeNegativePi_Method0)); + } + // delta lambda decay time + histos.fill(HIST("h2dLambdaDeltaDecayTime"), v0.p(), deltaDecayTimeLambda); if (doQANSigma) histos.fill(HIST("h2dNSigmaNegativeLambdaPi"), v0.p(), nSigmaNegativeLambdaPi); } - if (std::abs(v0.mAntiLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma) { + if (std::abs(v0.mAntiLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && ((v0pdg == 0) || (v0pdg == -3122))) { histos.fill(HIST("h2dDeltaTimeNegativeLambdaPr"), v0.p(), v0.eta(), deltaTimeNegativeLambdaPr); + if (calculationMethod.value == 2 && std::abs(timeNegativePr_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon && std::abs(timeNegativePr_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negLaPr"), negativeP, v0.negativeeta(), (timeNegativePr_Method0 - timeNegativePr_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negLaPr"), negativeP, v0.negativeeta(), (timeNegativePr_Method1 / timeNegativePr_Method0)); + } if (doQANSigma) histos.fill(HIST("h2dNSigmaNegativeLambdaPr"), v0.p(), nSigmaNegativeLambdaPr); } - if (std::abs(v0.mK0Short() - 0.497) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + if (std::abs(v0.mK0Short() - 0.497) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && ((v0pdg == 0) || (v0pdg == 310))) { histos.fill(HIST("h2dDeltaTimeNegativeK0ShortPi"), v0.p(), v0.eta(), deltaTimeNegativeK0ShortPi); + if (calculationMethod.value == 2 && std::abs(timeNegativePi_Method0 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon && std::abs(timeNegativePi_Method1 - o2::aod::v0data::kNoTOFValue) > o2::aod::v0data::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negK0Pi"), negativeP, v0.negativeeta(), (timeNegativePi_Method0 - timeNegativePi_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negK0Pi"), negativeP, v0.negativeeta(), (timeNegativePi_Method1 / timeNegativePi_Method0)); + } if (doQANSigma) histos.fill(HIST("h2dNSigmaNegativeK0ShortPi"), v0.p(), nSigmaNegativeK0ShortPi); } } } - // delta lambda decay time - histos.fill(HIST("h2dLambdaDeltaDecayTime"), v0.p(), deltaDecayTimeLambda); } } template - void processCascadeCandidate(TCollision const& collision, TCascade const& cascade, TTrack const& pTra, TTrack const& nTra, TTrack const& bTra) + void processCascadeCandidate(TCollision const& collision, TCascade const& cascade, TTrack const& pTra, TTrack const& nTra, TTrack const& bTra, int cascpdg) { // initialize from positions and momenta as needed - o2::track::TrackPar posTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxpos(), cascade.pypos(), cascade.pzpos()}, +1); - o2::track::TrackPar negTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxneg(), cascade.pyneg(), cascade.pzneg()}, -1); - o2::track::TrackPar bachTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.pxbach(), cascade.pybach(), cascade.pzbach()}, cascade.sign()); - o2::track::TrackPar cascTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.px(), cascade.py(), cascade.pz()}, cascade.sign()); + o2::track::TrackPar posTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxpos(), cascade.pypos(), cascade.pzpos()}, +1, false); + o2::track::TrackPar negTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxneg(), cascade.pyneg(), cascade.pzneg()}, -1, false); + o2::track::TrackPar bachTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.pxbach(), cascade.pybach(), cascade.pzbach()}, cascade.sign(), false); + o2::track::TrackPar cascTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.px(), cascade.py(), cascade.pz()}, cascade.sign(), false); + + float positiveP = std::hypot(cascade.pxpos(), cascade.pypos(), cascade.pzpos()); + float negativeP = std::hypot(cascade.pxneg(), cascade.pyneg(), cascade.pzneg()); + float bachelorP = std::hypot(cascade.pxbach(), cascade.pybach(), cascade.pzbach()); // start calculation: calculate velocities - float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); - float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); - float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityBachelorPi = velocity(bachTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityBachelorKa = velocity(bachTrack.getP(), o2::constants::physics::MassKaonCharged); float velocityXi = velocity(cascTrack.getP(), o2::constants::physics::MassXiMinus); float velocityOm = velocity(cascTrack.getP(), o2::constants::physics::MassOmegaMinus); float velocityLa = velocity(std::hypot(cascade.pxlambda(), cascade.pylambda(), cascade.pzlambda()), o2::constants::physics::MassLambda); - // calculate daughter length to TOF intercept - float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? - float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? - float lengthBachelor = findInterceptLength(bachTrack, d_bz); // FIXME: tofPosition ok? adjust? - // calculate mother lengths float lengthV0 = std::hypot(cascade.xlambda() - cascade.x(), cascade.ylambda() - cascade.y(), cascade.zlambda() - cascade.z()); float lengthCascade = o2::aod::cascdata::kNoTOFValue; ; const o2::math_utils::Point3D collVtx{collision.getX(), collision.getY(), collision.getZ()}; bool successPropag = o2::base::Propagator::Instance()->propagateToDCA(collVtx, cascTrack, d_bz, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrNONE); - float d = -1.0f, d3d = 0.0f; + float d = -1.0f; float linearToPV = std::hypot(cascade.x() - collision.getX(), cascade.y() - collision.getY(), cascade.z() - collision.getZ()); if (successPropag) { std::array cascCloseToPVPosition; @@ -755,7 +1126,7 @@ struct strangenesstofpid { // calculate 2D distance between two points d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1]); - d3d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1], cascade.z() - cascCloseToPVPosition[2]); // cross-check variable + // d3d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1], cascade.z() - cascCloseToPVPosition[2]); // cross-check variable float sinThetaOverTwo = d / (2.0f * trcCircleCascade.rC); lengthCascade = 2.0f * trcCircleCascade.rC * TMath::ASin(sinThetaOverTwo); lengthCascade *= sqrt(1.0f + cascTrack.getTgl() * cascTrack.getTgl()); @@ -769,12 +1140,161 @@ struct strangenesstofpid { float lambdaFlight = lengthV0 / velocityLa; float xiFlight = lengthCascade / velocityXi; float omFlight = lengthCascade / velocityOm; - float posFlightPi = lengthPositive / velocityPositivePi; - float posFlightPr = lengthPositive / velocityPositivePr; - float negFlightPi = lengthNegative / velocityNegativePi; - float negFlightPr = lengthNegative / velocityNegativePr; - float bachFlightPi = lengthBachelor / velocityBachelorPi; - float bachFlightKa = lengthBachelor / velocityBachelorKa; + float posFlightPi = o2::aod::cascdata::kNoTOFValue; + float posFlightPr = o2::aod::cascdata::kNoTOFValue; + float negFlightPi = o2::aod::cascdata::kNoTOFValue; + float negFlightPr = o2::aod::cascdata::kNoTOFValue; + float bachFlightPi = o2::aod::cascdata::kNoTOFValue; + float bachFlightKa = o2::aod::cascdata::kNoTOFValue; + + float posFlightPi_Method0 = o2::aod::cascdata::kNoTOFValue; + float posFlightPr_Method0 = o2::aod::cascdata::kNoTOFValue; + float negFlightPi_Method0 = o2::aod::cascdata::kNoTOFValue; + float negFlightPr_Method0 = o2::aod::cascdata::kNoTOFValue; + float bachFlightPi_Method0 = o2::aod::cascdata::kNoTOFValue; + float bachFlightKa_Method0 = o2::aod::cascdata::kNoTOFValue; + + float posFlightPi_Method1 = o2::aod::cascdata::kNoTOFValue; + float posFlightPr_Method1 = o2::aod::cascdata::kNoTOFValue; + float negFlightPi_Method1 = o2::aod::cascdata::kNoTOFValue; + float negFlightPr_Method1 = o2::aod::cascdata::kNoTOFValue; + float bachFlightPi_Method1 = o2::aod::cascdata::kNoTOFValue; + float bachFlightKa_Method1 = o2::aod::cascdata::kNoTOFValue; + + // actual time-of-flight of daughter calculation + if (calculationMethod.value == 0 || calculationMethod.value == 2) { + float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); + float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); + float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityBachelorPi = velocity(bachTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityBachelorKa = velocity(bachTrack.getP(), o2::constants::physics::MassKaonCharged); + + float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? + float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? + float lengthBachelor = findInterceptLength(bachTrack, d_bz); // FIXME: tofPosition ok? adjust? + + if (lengthPositive > 0 && pTra.hasTOF() && pTra.hasITS()) { + posFlightPi_Method0 = lengthPositive / velocityPositivePi; + posFlightPr_Method0 = lengthPositive / velocityPositivePr; + } + if (lengthNegative > 0 && nTra.hasTOF() && nTra.hasITS()) { + negFlightPi_Method0 = lengthNegative / velocityNegativePi; + negFlightPr_Method0 = lengthNegative / velocityNegativePr; + } + if (lengthBachelor > 0 && bTra.hasTOF() && bTra.hasITS()) { + bachFlightPi_Method0 = lengthBachelor / velocityBachelorPi; + bachFlightKa_Method0 = lengthBachelor / velocityBachelorKa; + } + } + + if (calculationMethod.value > 0) { + if (pTra.hasTOF() && pTra.hasITS()) { // calculate if signal present, otherwise skip + if (posTrack.getP() < propagationConfiguration.maxProtonMomentumForEloss.value && std::abs(pTra.tpcNSigmaPr()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar posTrackAsProton(posTrack); + posTrackAsProton.setPID(o2::track::PID::Proton); + calculateTOF(posTrackAsProton, posFlightPr_Method1); + } else { + posFlightPr_Method1 = posFlightPr_Method0; + } + + if (posTrack.getP() < propagationConfiguration.maxPionMomentumForEloss.value && std::abs(pTra.tpcNSigmaPi()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar posTrackAsPion(posTrack); + posTrackAsPion.setPID(o2::track::PID::Pion); + calculateTOF(posTrackAsPion, posFlightPi_Method1); + } else { + posFlightPi_Method1 = posFlightPi_Method0; + } + } + if (nTra.hasTOF() && nTra.hasITS()) { // calculate if signal present, otherwise skip + if (negTrack.getP() < propagationConfiguration.maxProtonMomentumForEloss.value && std::abs(nTra.tpcNSigmaPr()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar negTrackAsProton(negTrack); + negTrackAsProton.setPID(o2::track::PID::Proton); + calculateTOF(negTrackAsProton, negFlightPr_Method1); + } else { + negFlightPr_Method1 = negFlightPr_Method0; + } + + if (negTrack.getP() < propagationConfiguration.maxProtonMomentumForEloss.value && std::abs(nTra.tpcNSigmaPi()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar negTrackAsPion(negTrack); + negTrackAsPion.setPID(o2::track::PID::Pion); + calculateTOF(negTrackAsPion, negFlightPi_Method1); + } else { + negFlightPi_Method1 = negFlightPi_Method0; + } + } + if (bTra.hasTOF() && bTra.hasITS()) { // calculate if signal present, otherwise skip + if (bachTrack.getP() < propagationConfiguration.maxPionMomentumForEloss.value && std::abs(bTra.tpcNSigmaPi()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar bachTrackAsPion(bachTrack); + bachTrackAsPion.setPID(o2::track::PID::Pion); + calculateTOF(bachTrackAsPion, bachFlightPi_Method1); + } else { + bachFlightPi_Method1 = bachFlightPi_Method0; + } + + if (bachTrack.getP() < propagationConfiguration.maxKaonMomentumForEloss.value && std::abs(bTra.tpcNSigmaKa()) < propagationConfiguration.tpcNsigmaThreshold) { + o2::track::TrackPar bachTrackAsKaon(bachTrack); + bachTrackAsKaon.setPID(o2::track::PID::Kaon); + calculateTOF(bachTrackAsKaon, bachFlightKa_Method1); + } else { + bachFlightKa_Method1 = bachFlightKa_Method0; + } + } + } + + // assign values to be used in main calculation + if (calculationMethod.value == 0) { + posFlightPi = posFlightPi_Method0; + posFlightPr = posFlightPr_Method0; + negFlightPi = negFlightPi_Method0; + negFlightPr = negFlightPr_Method0; + bachFlightPi = bachFlightPi_Method0; + bachFlightKa = bachFlightKa_Method0; + } else { + posFlightPi = posFlightPi_Method1; + posFlightPr = posFlightPr_Method1; + negFlightPi = negFlightPi_Method1; + negFlightPr = negFlightPr_Method1; + bachFlightPi = bachFlightPi_Method1; + bachFlightKa = bachFlightKa_Method1; + } + + if (calculationMethod.value == 2) { + // do analysis of successes and failures + bool positiveSuccessMethod0Pr = std::abs(posFlightPr_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool negativeSuccessMethod0Pr = std::abs(negFlightPr_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool positiveSuccessMethod1Pr = std::abs(posFlightPr_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool negativeSuccessMethod1Pr = std::abs(negFlightPr_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool positiveSuccessMethod0Pi = std::abs(posFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool negativeSuccessMethod0Pi = std::abs(negFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool positiveSuccessMethod1Pi = std::abs(posFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool negativeSuccessMethod1Pi = std::abs(negFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + + bool bachelorSuccessMethod0Pi = std::abs(bachFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool bachelorSuccessMethod0Ka = std::abs(bachFlightKa_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool bachelorSuccessMethod1Pi = std::abs(bachFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + bool bachelorSuccessMethod1Ka = std::abs(bachFlightKa_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon; + + int encodedPositiveSuccessPi = positiveSuccessMethod0Pi + 2 * positiveSuccessMethod1Pi; + int encodedPositiveSuccessPr = positiveSuccessMethod0Pr + 2 * positiveSuccessMethod1Pr; + int encodedNegativeSuccessPi = negativeSuccessMethod0Pi + 2 * negativeSuccessMethod1Pi; + int encodedNegativeSuccessPr = negativeSuccessMethod0Pr + 2 * negativeSuccessMethod1Pr; + int encodedBachelorSuccessPi = bachelorSuccessMethod0Pi + 2 * bachelorSuccessMethod1Pi; + int encodedBachelorSuccessKa = bachelorSuccessMethod0Ka + 2 * bachelorSuccessMethod1Ka; + + if (pTra.hasTOF()) { + histos.fill(HIST("h2dSucessRateProton"), positiveP, encodedPositiveSuccessPr); + histos.fill(HIST("h2dSucessRatePion"), positiveP, encodedPositiveSuccessPi); + } + if (nTra.hasTOF()) { + histos.fill(HIST("h2dSucessRateProton"), negativeP, encodedNegativeSuccessPr); + histos.fill(HIST("h2dSucessRatePion"), negativeP, encodedNegativeSuccessPi); + } + if (bTra.hasTOF()) { + histos.fill(HIST("h2dSucessRateKaon"), bachelorP, encodedBachelorSuccessKa); + histos.fill(HIST("h2dSucessRatePion"), bachelorP, encodedBachelorSuccessPi); + } + } // initialize delta-times (actual PID variables) float posDeltaTimeAsXiPi = o2::aod::cascdata::kNoTOFValue, posDeltaTimeAsXiPr = o2::aod::cascdata::kNoTOFValue; @@ -784,19 +1304,19 @@ struct strangenesstofpid { float negDeltaTimeAsOmPi = o2::aod::cascdata::kNoTOFValue, negDeltaTimeAsOmPr = o2::aod::cascdata::kNoTOFValue; float bachDeltaTimeAsOmKa = o2::aod::cascdata::kNoTOFValue; - if (pTra.hasTOF()) { + if (pTra.hasTOF() && pTra.hasITS()) { posDeltaTimeAsXiPi = (pTra.tofSignal() - pTra.tofEvTime()) - (xiFlight + lambdaFlight + posFlightPi); posDeltaTimeAsXiPr = (pTra.tofSignal() - pTra.tofEvTime()) - (xiFlight + lambdaFlight + posFlightPr); posDeltaTimeAsOmPi = (pTra.tofSignal() - pTra.tofEvTime()) - (omFlight + lambdaFlight + posFlightPi); posDeltaTimeAsOmPr = (pTra.tofSignal() - pTra.tofEvTime()) - (omFlight + lambdaFlight + posFlightPr); } - if (nTra.hasTOF()) { + if (nTra.hasTOF() && nTra.hasITS()) { negDeltaTimeAsXiPi = (nTra.tofSignal() - nTra.tofEvTime()) - (xiFlight + lambdaFlight + negFlightPi); negDeltaTimeAsXiPr = (nTra.tofSignal() - nTra.tofEvTime()) - (xiFlight + lambdaFlight + negFlightPr); negDeltaTimeAsOmPi = (nTra.tofSignal() - nTra.tofEvTime()) - (omFlight + lambdaFlight + negFlightPi); negDeltaTimeAsOmPr = (nTra.tofSignal() - nTra.tofEvTime()) - (omFlight + lambdaFlight + negFlightPr); } - if (bTra.hasTOF()) { + if (bTra.hasTOF() && bTra.hasITS()) { bachDeltaTimeAsXiPi = (bTra.tofSignal() - bTra.tofEvTime()) - (xiFlight + bachFlightPi); bachDeltaTimeAsOmKa = (bTra.tofSignal() - bTra.tofEvTime()) - (omFlight + bachFlightKa); } @@ -806,17 +1326,11 @@ struct strangenesstofpid { posDeltaTimeAsOmPi, posDeltaTimeAsOmPr, negDeltaTimeAsOmPi, negDeltaTimeAsOmPr, bachDeltaTimeAsOmKa); float nSigmaXiLaPr = o2::aod::cascdata::kNoTOFValue; - ; float nSigmaXiLaPi = o2::aod::cascdata::kNoTOFValue; - ; float nSigmaXiPi = o2::aod::cascdata::kNoTOFValue; - ; float nSigmaOmLaPr = o2::aod::cascdata::kNoTOFValue; - ; float nSigmaOmLaPi = o2::aod::cascdata::kNoTOFValue; - ; float nSigmaOmKa = o2::aod::cascdata::kNoTOFValue; - ; // go for Nsigma values if requested if (doNSigmas && nSigmaCalibLoaded) { @@ -852,25 +1366,58 @@ struct strangenesstofpid { } if (doQA) { - // fill QA histograms for cross-checking - histos.fill(HIST("hArcDebug"), cascade.p(), lengthCascade - d3d); // for debugging purposes + // length factor due to eta (to offset e-loss) + float positiveCosine = 1.0f / sqrt(1.0f + posTrack.getTgl() * posTrack.getTgl()); + float negativeCosine = 1.0f / sqrt(1.0f + negTrack.getTgl() * negTrack.getTgl()); + float bachelorCosine = 1.0f / sqrt(1.0f + bachTrack.getTgl() * bachTrack.getTgl()); + if (propagationConfiguration.correctELossInclination.value == false) { + negativeCosine = positiveCosine = bachelorCosine = 1.0f; + } if (cascade.dcaV0daughters() < cascadeGroup.qaV0DCADau && cascade.dcacascdaughters() < cascadeGroup.qaCascDCADau && cascade.v0cosPA(collision.getX(), collision.getY(), collision.getZ()) > cascadeGroup.qaV0CosPA && cascade.casccosPA(collision.getX(), collision.getY(), collision.getZ()) > cascadeGroup.qaCascCosPA) { if (cascade.sign() < 0) { - if (std::abs(cascade.mXi() - 1.32171) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma) { + if (std::abs(cascade.mXi() - 1.32171) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && ((cascpdg == 0) || (cascpdg == 3312))) { histos.fill(HIST("h2dposDeltaTimeAsXiPr"), cascade.p(), cascade.eta(), posDeltaTimeAsXiPr); histos.fill(HIST("h2dnegDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), negDeltaTimeAsXiPi); histos.fill(HIST("h2dbachDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), bachDeltaTimeAsXiPi); + if (calculationMethod.value == 2) { + if (std::abs(posFlightPr_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(posFlightPr_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posXiPr"), positiveP, cascade.positiveeta(), (posFlightPr_Method0 - posFlightPr_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posXiPr"), positiveP, cascade.positiveeta(), (posFlightPr_Method1 / posFlightPr_Method0)); + } + if (std::abs(negFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(negFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negXiPi"), negativeP, cascade.negativeeta(), (negFlightPi_Method0 - negFlightPi_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negXiPi"), negativeP, cascade.negativeeta(), (negFlightPi_Method1 / negFlightPi_Method0)); + } + if (std::abs(bachFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(bachFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_bachXiPi"), bachelorP, cascade.bacheloreta(), (bachFlightPi_Method0 - bachFlightPi_Method1) * bachelorCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_bachXiPi"), bachelorP, cascade.bacheloreta(), (bachFlightPi_Method1 / bachFlightPi_Method0)); + } + } if (doQANSigma) { histos.fill(HIST("h2dNSigmaXiLaPi"), cascade.p(), nSigmaXiLaPi); histos.fill(HIST("h2dNSigmaXiLaPr"), cascade.p(), nSigmaXiLaPr); histos.fill(HIST("h2dNSigmaXiPi"), cascade.p(), nSigmaXiPi); } } - if (std::abs(cascade.mOmega() - 1.67245) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < cascadeGroup.qaTPCNSigma) { + if (std::abs(cascade.mOmega() - 1.67245) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < cascadeGroup.qaTPCNSigma && ((cascpdg == 0) || (cascpdg == 3334))) { histos.fill(HIST("h2dposDeltaTimeAsOmPr"), cascade.p(), cascade.eta(), posDeltaTimeAsOmPr); histos.fill(HIST("h2dnegDeltaTimeAsOmPi"), cascade.p(), cascade.eta(), negDeltaTimeAsOmPi); histos.fill(HIST("h2dbachDeltaTimeAsOmKa"), cascade.p(), cascade.eta(), bachDeltaTimeAsOmKa); + if (calculationMethod.value == 2) { + if (std::abs(posFlightPr_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(posFlightPr_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posOmPr"), positiveP, cascade.positiveeta(), (posFlightPr_Method0 - posFlightPr_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posOmPr"), positiveP, cascade.positiveeta(), (posFlightPr_Method1 / posFlightPr_Method0)); + } + if (std::abs(negFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(negFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negOmPi"), negativeP, cascade.negativeeta(), (negFlightPi_Method0 - negFlightPi_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negOmPi"), negativeP, cascade.negativeeta(), (negFlightPi_Method1 / negFlightPi_Method0)); + } + if (std::abs(bachFlightKa_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(bachFlightKa_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_bachOmKa"), bachelorP, cascade.bacheloreta(), (bachFlightKa_Method0 - bachFlightKa_Method1) * bachelorCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_bachOmKa"), bachelorP, cascade.bacheloreta(), (bachFlightKa_Method1 / bachFlightKa_Method0)); + } + } if (doQANSigma) { histos.fill(HIST("h2dNSigmaOmLaPi"), cascade.p(), nSigmaOmLaPi); histos.fill(HIST("h2dNSigmaOmLaPr"), cascade.p(), nSigmaOmLaPr); @@ -878,20 +1425,48 @@ struct strangenesstofpid { } } } else { - if (std::abs(cascade.mXi() - 1.32171) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma) { + if (std::abs(cascade.mXi() - 1.32171) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && ((cascpdg == 0) || (cascpdg == -3312))) { histos.fill(HIST("h2dposDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), posDeltaTimeAsXiPi); histos.fill(HIST("h2dnegDeltaTimeAsXiPr"), cascade.p(), cascade.eta(), negDeltaTimeAsXiPr); histos.fill(HIST("h2dbachDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), bachDeltaTimeAsXiPi); + if (calculationMethod.value == 2) { + if (std::abs(posFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(posFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posXiPi"), positiveP, cascade.positiveeta(), (posFlightPi_Method0 - posFlightPi_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posXiPi"), positiveP, cascade.positiveeta(), (posFlightPi_Method1 / posFlightPi_Method1)); + } + if (std::abs(negFlightPr_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(negFlightPr_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negXiPr"), negativeP, cascade.negativeeta(), (negFlightPr_Method0 - negFlightPr_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negXiPr"), negativeP, cascade.negativeeta(), (negFlightPr_Method1 / negFlightPr_Method0)); + } + if (std::abs(bachFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(bachFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_bachXiPi"), bachelorP, cascade.bacheloreta(), (bachFlightPi_Method0 - bachFlightPi_Method1) * bachelorCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_bachXiPi"), bachelorP, cascade.bacheloreta(), (bachFlightPi_Method1 / bachFlightPi_Method0)); + } + } if (doQANSigma) { histos.fill(HIST("h2dNSigmaXiLaPi"), cascade.p(), nSigmaXiLaPi); histos.fill(HIST("h2dNSigmaXiLaPr"), cascade.p(), nSigmaXiLaPr); histos.fill(HIST("h2dNSigmaXiPi"), cascade.p(), nSigmaXiPi); } } - if (std::abs(cascade.mOmega() - 1.67245) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < cascadeGroup.qaTPCNSigma) { + if (std::abs(cascade.mOmega() - 1.67245) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < cascadeGroup.qaTPCNSigma && ((cascpdg == 0) || (cascpdg == -3334))) { histos.fill(HIST("h2dposDeltaTimeAsOmPi"), cascade.p(), cascade.eta(), posDeltaTimeAsOmPi); histos.fill(HIST("h2dnegDeltaTimeAsOmPr"), cascade.p(), cascade.eta(), negDeltaTimeAsOmPr); histos.fill(HIST("h2dbachDeltaTimeAsOmKa"), cascade.p(), cascade.eta(), bachDeltaTimeAsOmKa); + if (calculationMethod.value == 2) { + if (std::abs(posFlightPi_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(posFlightPi_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_posOmPi"), positiveP, cascade.positiveeta(), (posFlightPi_Method0 - posFlightPi_Method1) * positiveCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_posOmPi"), positiveP, cascade.positiveeta(), (posFlightPi_Method1 / posFlightPi_Method1)); + } + if (std::abs(negFlightPr_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(negFlightPr_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_negOmPr"), negativeP, cascade.negativeeta(), (negFlightPr_Method0 - negFlightPr_Method1) * negativeCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_negOmPr"), negativeP, cascade.negativeeta(), (negFlightPr_Method1 / negFlightPr_Method0)); + } + if (std::abs(bachFlightKa_Method0 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon && std::abs(bachFlightKa_Method1 - o2::aod::cascdata::kNoTOFValue) > o2::aod::cascdata::kEpsilon) { + histos.fill(HIST("hDeltaTimeMethodsVsP_bachOmKa"), bachelorP, cascade.bacheloreta(), (bachFlightKa_Method0 - bachFlightKa_Method1) * bachelorCosine); + histos.fill(HIST("hRatioTimeMethodsVsP_bachOmKa"), bachelorP, cascade.bacheloreta(), (bachFlightKa_Method1 / bachFlightKa_Method1)); + } + } if (doQANSigma) { histos.fill(HIST("h2dNSigmaOmLaPi"), cascade.p(), nSigmaOmLaPi); histos.fill(HIST("h2dNSigmaOmLaPr"), cascade.p(), nSigmaOmLaPr); @@ -928,7 +1503,7 @@ struct strangenesstofpid { auto pTra = V0.posTrack_as(); auto nTra = V0.negTrack_as(); - processV0Candidate(primaryVertex, V0, pTra, nTra); + processV0Candidate(primaryVertex, V0, pTra, nTra, 0); } } @@ -947,7 +1522,7 @@ struct strangenesstofpid { auto pTra = cascade.posTrack_as(); auto nTra = cascade.negTrack_as(); auto bTra = cascade.bachelor_as(); - processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra); + processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra, 0); } } } @@ -977,7 +1552,66 @@ struct strangenesstofpid { auto pTra = V0.posTrackExtra_as(); auto nTra = V0.negTrackExtra_as(); - processV0Candidate(primaryVertex, V0, pTra, nTra); + processV0Candidate(primaryVertex, V0, pTra, nTra, 0); + } + } + + if (calculateCascades.value) { + for (const auto& cascade : cascades) { + // for storing whatever is the relevant quantity for the PV + o2::dataformats::VertexBase primaryVertex; + if (cascade.has_straCollision()) { + auto const& collision = cascade.straCollision_as>(); + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + primaryVertex.setCov(1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6); + } else { + primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); + } + + auto pTra = cascade.posTrackExtra_as(); + auto nTra = cascade.negTrackExtra_as(); + auto bTra = cascade.bachTrackExtra_as(); + processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra, 0); + } + } + } + + void processDerivedDataMCTest(soa::Join const& collisions, V0DerivedDatasMC const& V0s, CascDerivedDatasMC const& cascades, dauTracks const&, aod::V0MCCores const& v0mcs, aod::CascMCCores const& cascmcs) + { + // Fire up CCDB with first collision in record. If no collisions, bypass + if (useCustomRunNumber || collisions.size() < 1) { + initCCDB(manualRunNumber); + } else { + auto collision = collisions.begin(); + initCCDB(collision.runNumber()); + } + + if (calculateV0s.value) { + for (const auto& V0 : V0s) { + // for storing whatever is the relevant quantity for the PV + o2::dataformats::VertexBase primaryVertex; + if (V0.has_straCollision()) { + auto const& collision = V0.straCollision_as>(); + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + // cov: won't be used anyways, all fine + primaryVertex.setCov(1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6); + } else { + primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); + } + + // check association + int v0pdg = 0; + if (V0.v0MCCoreId() > -1) { + auto v0mc = v0mcs.rawIteratorAt(V0.v0MCCoreId()); + v0pdg = v0mc.pdgCode(); + if (std::abs(v0pdg) != 3122 && v0pdg != 310) { + continue; // only associated from this point on + } + } + + auto pTra = V0.posTrackExtra_as(); + auto nTra = V0.negTrackExtra_as(); + processV0Candidate(primaryVertex, V0, pTra, nTra, v0pdg); } } @@ -993,16 +1627,27 @@ struct strangenesstofpid { primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); } + // check association + int cascpdg = 0; + if (cascade.cascMCCoreId() > -1) { + auto cascmc = cascmcs.rawIteratorAt(cascade.cascMCCoreId()); + cascpdg = cascmc.pdgCode(); + if (std::abs(cascpdg) != 3312 && std::abs(cascpdg) != 3334) { + continue; // only associated from this point on + } + } + auto pTra = cascade.posTrackExtra_as(); auto nTra = cascade.negTrackExtra_as(); auto bTra = cascade.bachTrackExtra_as(); - processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra); + processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra, cascpdg); } } } - PROCESS_SWITCH(strangenesstofpid, processStandardData, "Process standard data", true); - PROCESS_SWITCH(strangenesstofpid, processDerivedData, "Process derived data", false); + PROCESS_SWITCH(strangenesstofpid, processStandardData, "Process standard data", false); + PROCESS_SWITCH(strangenesstofpid, processDerivedData, "Process derived data", true); + PROCESS_SWITCH(strangenesstofpid, processDerivedDataMCTest, "Process derived data / MC with assoc / not for analysis", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Strangeness/v0selector.cxx b/PWGLF/TableProducer/Strangeness/v0selector.cxx index 7d06871d78c..1d5d392b358 100644 --- a/PWGLF/TableProducer/Strangeness/v0selector.cxx +++ b/PWGLF/TableProducer/Strangeness/v0selector.cxx @@ -36,6 +36,10 @@ using namespace o2::framework::expressions; struct V0SelectorTask { Produces v0FlagTable; + Configurable selectK0S{"selectK0S", true, "Check V0s for K0S cuts"}; + Configurable selectLambda{"selectLambda", true, "Check V0s for Lambda cuts"}; + Configurable selectAntiLambda{"selectAntiLambda", true, "Check V0s for AntiLambda cuts"}; + Configurable> K0SPtBins{"K0SPtBins", {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0}, "K0S pt Vals"}; Configurable> K0SRminVals{"K0SRminVals", {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, "K0S min R values"}; Configurable> K0SRmaxVals{"K0SRmaxVals", {40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0}, "K0S max R values"}; @@ -85,7 +89,7 @@ struct V0SelectorTask { Configurable> AntiLambdaMassLowVals{"AntiLambdaMassLowVals", {1.08, 1.08, 1.08, 1.08, 1.08, 1.08, 1.08, 1.08}, "AntiLambda mass cut lower values (MeV)"}; Configurable> AntiLambdaMassHighVals{"AntiLambdaMassHighVals", {1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125}, "AntiLambda mass cut upper values (MeV)"}; - Configurable randomSelection{"randomSelection", true, "Randomly select V0s"}; + Configurable randomSelection{"randomSelection", false, "Randomly select V0s"}; Configurable> K0SFraction{"K0SFraction", {2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0}, "Fraction of K0S to randomly select"}; Configurable> LambdaFraction{"LambdaFraction", {2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0}, "Fraction of Lambda to randomly select"}; Configurable> AntiLambdaFraction{"AntiLambdaFraction", {2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0}, "Fraction of AntiLambda to randomly select"}; @@ -277,13 +281,16 @@ struct V0SelectorTask { { for (const auto& v0 : v0s) { uint8_t flag = 0; - flag += K0SCuts(collision, v0) * aod::v0flags::FK0S; - flag += LambdaCuts(collision, v0) * aod::v0flags::FLAMBDA; - flag += AntiLambdaCuts(collision, v0) * aod::v0flags::FANTILAMBDA; + if (selectK0S) + flag += K0SCuts(collision, v0) * aod::v0flags::FK0S; + if (selectLambda) + flag += LambdaCuts(collision, v0) * aod::v0flags::FLAMBDA; + if (selectAntiLambda) + flag += AntiLambdaCuts(collision, v0) * aod::v0flags::FANTILAMBDA; if (flag == 0) flag += aod::v0flags::FREJECTED; - else + else if (randomSelection) flag += RandomlyReject(v0, flag) * aod::v0flags::FREJECTED; v0FlagTable(flag); diff --git a/PWGLF/Tasks/GlobalEventProperties/dndeta-mft-pp.cxx b/PWGLF/Tasks/GlobalEventProperties/dndeta-mft-pp.cxx index c90a3d89474..a37b4f8c368 100644 --- a/PWGLF/Tasks/GlobalEventProperties/dndeta-mft-pp.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/dndeta-mft-pp.cxx @@ -35,6 +35,7 @@ #include "TFile.h" +#include #include #include #include @@ -91,6 +92,7 @@ struct PseudorapidityDensityMFT { "max allowed Z difference for reconstructed collisions (cm)"}; Configurable usePhiCut{"usePhiCut", true, "use azimuthal angle cut"}; + Configurable useDCAxyCut{"useDCAxyCut", false, "use DCAxy cut"}; Configurable cfgPhiCut{"cfgPhiCut", 0.1f, "Cut on azimuthal angle of MFT tracks"}; Configurable cfgPhiCut1{"cfgPhiCut1", 0.0f, @@ -108,6 +110,7 @@ struct PseudorapidityDensityMFT { Configurable cfgnEta2{"cfgnEta2", -1.0f, "Cut on eta1"}; Configurable cfgChi2NDFMax{"cfgChi2NDFMax", 2000.0f, "Max allowed chi2/NDF for MFT tracks"}; + Configurable maxDCAxy{"maxDCAxy", 2.0f, "Cut on dcaXY"}; HistogramRegistry registry{ "registry", @@ -588,6 +591,11 @@ struct PseudorapidityDensityMFT { if ((phi <= 0.02) || ((phi >= 3.10) && (phi <= 3.23)) || (phi >= 6.21)) continue; } + float dcaxy_cut = retrack.bestDCAXY(); + if (useDCAxyCut) { + if (dcaxy_cut > maxDCAxy) + continue; + } if ((cfgnEta1 < track.eta()) && (track.eta() < cfgnEta2) && track.nClusters() >= cfgnCluster && retrack.ambDegree() > 0 && chi2ndf < cfgChi2NDFMax && (phi > cfgPhiCut1 && phi < cfgPhiCut2)) { registry.fill(HIST("Tracks/2Danalysis/EtaZvtx"), track.eta(), z); } @@ -628,6 +636,11 @@ struct PseudorapidityDensityMFT { if ((phi <= 0.02) || ((phi >= 3.10) && (phi <= 3.23)) || (phi >= 6.21)) continue; } + float dcaxy_cut = retrack.bestDCAXY(); + if (useDCAxyCut) { + if (dcaxy_cut > maxDCAxy) + continue; + } if ((cfgnEta1 < track.eta()) && (track.eta() < cfgnEta2) && track.nClusters() >= cfgnCluster && retrack.ambDegree() > 0 && chi2ndf < cfgChi2NDFMax && (phi > cfgPhiCut1 && phi < cfgPhiCut2)) { registry.fill(HIST("Tracks/Control/Chi2NDF"), chi2ndf); registry.fill(HIST("Tracks/2Danalysis/EtaZvtx_sel8"), track.eta(), z); @@ -646,12 +659,17 @@ struct PseudorapidityDensityMFT { float ndf = std::max(2.0f * track.nClusters() - 5.0f, 1.0f); float chi2ndf = track.chi2() / ndf; float phi = track.phi(); + float dcaxy_cut = retrack.bestDCAXY(); o2::math_utils::bringTo02Pi(phi); if ((cfgnEta1 < track.eta()) && (track.eta() < cfgnEta2) && track.nClusters() >= cfgnCluster && chi2ndf < cfgChi2NDFMax && (phi > cfgPhiCut1 && phi < cfgPhiCut2)) { if (usePhiCut) { if ((phi <= 0.02) || ((phi >= 3.10) && (phi <= 3.23)) || (phi >= 6.21)) continue; } + if (useDCAxyCut) { + if (dcaxy_cut > maxDCAxy) + continue; + } registry.fill(HIST("TracksEtaZvtx"), track.eta(), z); if (midtracks.size() > 0 && retrack.ambDegree() > 0) { registry.fill(HIST("Tracks/EtaZvtx_gt0"), track.eta(), z); diff --git a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx index 6637d6f2dcd..1de0773fa0b 100644 --- a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx @@ -147,6 +147,7 @@ struct HeavyionMultiplicity { ConfigurableAxis centralityBinning{"centralityBinning", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, ""}; ConfigurableAxis occupancyBin{"occupancyBin", {VARIABLE_WIDTH, 0, 500, 1000, 2000, 5000, 10000}, ""}; ConfigurableAxis centBinGen{"centBinGen", {VARIABLE_WIDTH, 0, 500, 1000, 2000, 5000, 10000}, ""}; + ConfigurableAxis binsImpactPar{"binsImpactPar", {VARIABLE_WIDTH, 0.0, 3.00065, 4.28798, 6.14552, 7.6196, 8.90942, 10.0897, 11.2002, 12.2709, 13.3167, 14.4173, 23.2518}, "Binning of the impact parameter axis"}; Configurable isApplySameBunchPileup{"isApplySameBunchPileup", true, "Enable SameBunchPileup cut"}; Configurable isApplyGoodZvtxFT0vsPV{"isApplyGoodZvtxFT0vsPV", true, "Enable GoodZvtxFT0vsPV cut"}; @@ -178,6 +179,7 @@ struct HeavyionMultiplicity { AxisSpec axisPt = {ptHistBin, "pT", "pTAxis"}; AxisSpec axisOccupancy = {occupancyBin, "occupancy", "OccupancyAxis"}; AxisSpec axisCentBinGen = {centBinGen, "GenCentrality", "CentGenAxis"}; + AxisSpec impactParAxis = {binsImpactPar, "Impact Parameter"}; histos.add("EventHist", "EventHist", kTH1D, {axisEvent}, false); histos.add("VtxZHist", "VtxZHist", kTH1D, {axisVtxZ}, false); @@ -231,8 +233,11 @@ struct HeavyionMultiplicity { if (doprocessCorrelation) { histos.add("GlobalMult_vs_FT0A", "GlobalMult_vs_FT0A", kTH2F, {axisMult, axisFt0aMult}, true); histos.add("GlobalMult_vs_FT0C", "GlobalMult_vs_FT0C", kTH2F, {axisMult, axisFt0cMult}, true); + histos.add("Centrality_vs_FT0C", "Centrality_vs_FT0C", kTH2F, {centAxis, axisFt0cMult}, true); histos.add("NPVtracks_vs_FT0C", "NPVtracks_vs_FT0C", kTH2F, {axisPV, axisFt0cMult}, true); histos.add("GlobalMult_vs_FV0A", "GlobalMult_vs_FV0A", kTH2F, {axisMult, axisFv0aMult}, true); + histos.add("Centrality_vs_FV0A", "Centrality_vs_FV0A", kTH2F, {centAxis, axisFv0aMult}, true); + histos.add("CentFT0Ccentrality_vs_GlobalMult", "CentFT0Ccentrality_vs_GlobalMult", kTH2F, {centAxis, axisMult}, true); histos.add("NPVtracks_vs_GlobalMult", "NPVtracks_vs_GlobalMult", kTH2F, {axisPV, axisMult}, true); } @@ -269,6 +274,21 @@ struct HeavyionMultiplicity { histos.add("mult10_vs_FT0C", "mult10_vs_FT0C", kTH2F, {axisMult, axisCentBinGen}, true); histos.add("mult10_vs_FT0A", "mult10_vs_FT0A", kTH2F, {axisMult, axisCentBinGen}, true); } + + if (doprocessEvtLossSigLossMC) { + histos.add("MCEventHist", "MCEventHist", kTH1F, {axisEvent}, false); + auto hstat = histos.get(HIST("MCEventHist")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "All MC events"); + x->SetBinLabel(2, "MC events with atleast one reco event"); + histos.add("hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); + histos.add("hImpactParameterRec", "Impact parameter of selected MC events", kTH1F, {impactParAxis}); + histos.add("hImpactParvsCentrRec", "Impact parameter of selected MC events vs centrality", kTH2F, {axisCent, impactParAxis}); + histos.add("hgendndetaBeforeEvtSel", "Eta of all generated particles", kTH1F, {axisEta}); + histos.add("hgendndetaAfterEvtSel", "Eta of generated particles after EvtSel", kTH1F, {axisEta}); + histos.add("hgendndetaVscentBeforeEvtSel", "hgendndetaBeforeEvtSel vs centrality", kTH2F, {axisEta, impactParAxis}); + histos.add("hgendndetaVscentAfterEvtSel", "hgendndetaAfterEvtSel vs centrality", kTH2F, {axisEta, impactParAxis}); + } } template @@ -416,7 +436,6 @@ struct HeavyionMultiplicity { } } } - PROCESS_SWITCH(HeavyionMultiplicity, processData, "process data CentFT0C", false); void processCorrelation(CollisionDataTable::iterator const& cols, FilTrackDataTable const& tracks) { @@ -435,13 +454,16 @@ struct HeavyionMultiplicity { } nchTracks++; } + histos.fill(HIST("GlobalMult_vs_FT0A"), nchTracks, cols.multFT0A()); histos.fill(HIST("GlobalMult_vs_FT0C"), nchTracks, cols.multFT0C()); + histos.fill(HIST("Centrality_vs_FT0C"), cols.centFT0C(), cols.multFT0C()); histos.fill(HIST("NPVtracks_vs_FT0C"), cols.multNTracksPV(), cols.multFT0C()); histos.fill(HIST("GlobalMult_vs_FV0A"), nchTracks, cols.multFV0A()); + histos.fill(HIST("Centrality_vs_FV0A"), cols.centFV0A(), cols.multFV0A()); + histos.fill(HIST("CentFT0Ccentrality_vs_GlobalMult"), cols.centFT0C(), nchTracks); histos.fill(HIST("NPVtracks_vs_GlobalMult"), cols.multNTracksPV(), nchTracks); } - PROCESS_SWITCH(HeavyionMultiplicity, processCorrelation, "do correlation study in data", false); void processMonteCarlo(CollisionMCTrueTable::iterator const&, CollisionMCRecTable const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { @@ -541,7 +563,6 @@ struct HeavyionMultiplicity { } // track (mcgen) loop } // collision loop } - PROCESS_SWITCH(HeavyionMultiplicity, processMonteCarlo, "process MC CentFT0C", false); void processMCpTefficiency(CollisionMCTrueTable::iterator const&, CollisionMCRecTable const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { @@ -589,7 +610,6 @@ struct HeavyionMultiplicity { } } } - PROCESS_SWITCH(HeavyionMultiplicity, processMCpTefficiency, "process MC pTefficiency", false); void processMCcheckFakeTracks(CollisionMCTrueTable::iterator const&, CollisionMCRecTable const& RecCols, FilTrackMCRecTable const& RecTracks) { @@ -628,7 +648,6 @@ struct HeavyionMultiplicity { } } } - PROCESS_SWITCH(HeavyionMultiplicity, processMCcheckFakeTracks, "Check Fake tracks", false); void processStrangeYield(CollisionDataTable::iterator const& cols, V0TrackCandidates const&, aod::V0Datas const& v0data) { @@ -671,7 +690,6 @@ struct HeavyionMultiplicity { histos.fill(HIST("AntiLambdaCentEtaMass"), selColCent(cols), v0track.eta(), v0track.mAntiLambda()); } } - PROCESS_SWITCH(HeavyionMultiplicity, processStrangeYield, "Strange particle yield", false); void processppData(ColDataTablepp::iterator const& cols, FilTrackDataTable const& tracks) { @@ -696,7 +714,6 @@ struct HeavyionMultiplicity { } } // track loop } - PROCESS_SWITCH(HeavyionMultiplicity, processppData, "process pp data", false); void processppMonteCarlo(CollisionMCTrueTable::iterator const&, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { @@ -796,7 +813,6 @@ struct HeavyionMultiplicity { } // track (mcgen) loop } // collision loop } - PROCESS_SWITCH(HeavyionMultiplicity, processppMonteCarlo, "process pp MC", false); void processGen(aod::McCollisions::iterator const&, aod::McParticles const& GenParticles) { @@ -836,7 +852,73 @@ struct HeavyionMultiplicity { histos.fill(HIST("dndeta10_vs_FT0C"), particle.eta(), multFT0C); } } + + void processEvtLossSigLossMC(soa::Join::iterator const& mcCollision, CollisionMCRecTable const& RecCols, TrackMCTrueTable const& GenParticles) + { + if (isApplyInelgt0 && !mcCollision.isInelGt0()) { + return; + } + if (std::abs(mcCollision.posZ()) >= vtxRange) { + return; + } + // All generated events + histos.fill(HIST("MCEventHist"), 1); + histos.fill(HIST("hImpactParameterGen"), mcCollision.impactParameter()); + + bool atLeastOne = false; + auto centrality = -999.; + auto numcontributors = -999; + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) { + continue; + } + if (std::abs(RecCol.posZ()) >= vtxRange) { + continue; + } + if (RecCol.numContrib() <= numcontributors) { + continue; + } else { + numcontributors = RecCol.numContrib(); + } + centrality = selColCent(RecCol); + atLeastOne = true; + } + + // Generated events with at least one reconstructed collision (event loss estimation) + if (atLeastOne) { + histos.fill(HIST("MCEventHist"), 2); + histos.fill(HIST("hImpactParameterRec"), mcCollision.impactParameter()); + histos.fill(HIST("hImpactParvsCentrRec"), centrality, mcCollision.impactParameter()); + } + + for (const auto& particle : GenParticles) { + + if (!isGenTrackSelected(particle)) { + continue; + } + + // All generated particles + histos.fill(HIST("hgendndetaBeforeEvtSel"), particle.eta()); + histos.fill(HIST("hgendndetaVscentBeforeEvtSel"), particle.eta(), mcCollision.impactParameter()); + + if (atLeastOne) { + // All generated particles with at least one reconstructed collision (signal loss estimation) + histos.fill(HIST("hgendndetaAfterEvtSel"), particle.eta()); + histos.fill(HIST("hgendndetaVscentAfterEvtSel"), particle.eta(), mcCollision.impactParameter()); + } + } + } + + PROCESS_SWITCH(HeavyionMultiplicity, processData, "process data CentFT0C", false); + PROCESS_SWITCH(HeavyionMultiplicity, processCorrelation, "do correlation study in data", false); + PROCESS_SWITCH(HeavyionMultiplicity, processMonteCarlo, "process MC CentFT0C", false); + PROCESS_SWITCH(HeavyionMultiplicity, processMCpTefficiency, "process MC pTefficiency", false); + PROCESS_SWITCH(HeavyionMultiplicity, processMCcheckFakeTracks, "Check Fake tracks", false); + PROCESS_SWITCH(HeavyionMultiplicity, processStrangeYield, "Strange particle yield", false); + PROCESS_SWITCH(HeavyionMultiplicity, processppData, "process pp data", false); + PROCESS_SWITCH(HeavyionMultiplicity, processppMonteCarlo, "process pp MC", false); PROCESS_SWITCH(HeavyionMultiplicity, processGen, "process pure MC gen", false); + PROCESS_SWITCH(HeavyionMultiplicity, processEvtLossSigLossMC, "process Signal Loss, Event Loss", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx index 465b0caa8a3..078d8aff97a 100644 --- a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx @@ -221,8 +221,11 @@ struct UccZdc { bool calibrationsLoaded = false; } cfgNch; + int currentRunNumber; + void init(InitContext const&) { + currentRunNumber = -1; const char* tiT0A{"T0A (#times 1/100, 3.5 < #eta < 4.9)"}; const char* tiT0C{"T0C (#times 1/100, -3.3 < #eta < -2.1)"}; const char* tiT0M{"T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9)"}; @@ -423,6 +426,7 @@ struct UccZdc { LOG(info) << "\tminPt=" << minPt.value; LOG(info) << "\tmaxPt=" << maxPt.value; LOG(info) << "\tmaxPtSpectra=" << maxPtSpectra.value; + LOG(info) << "\tcurrentRunNumber= " << currentRunNumber; ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); @@ -602,7 +606,14 @@ struct UccZdc { bool skipEvent{false}; if (useMidRapNchSel) { - loadNchCalibrations(foundBC.timestamp()); + + const int nextRunNumber{foundBC.runNumber()}; + if (currentRunNumber != nextRunNumber) { + loadNchCalibrations(foundBC.timestamp()); + currentRunNumber = nextRunNumber; + LOG(info) << "\tcurrentRunNumber= " << currentRunNumber << " timeStamp = " << foundBC.timestamp(); + } + if (!(cfgNch.hMeanNch && cfgNch.hSigmaNch)) return; @@ -787,7 +798,14 @@ struct UccZdc { bool skipEvent{false}; if (useMidRapNchSel) { - loadNchCalibrations(foundBC.timestamp()); + + const int nextRunNumber{foundBC.runNumber()}; + if (currentRunNumber != nextRunNumber) { + loadNchCalibrations(foundBC.timestamp()); + currentRunNumber = nextRunNumber; + LOG(info) << "\tcurrentRunNumber= " << currentRunNumber << " timeStamp = " << foundBC.timestamp(); + } + if (!(cfgNch.hMeanNch && cfgNch.hSigmaNch)) return; diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index cc23b8d0544..8f134d60175 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -155,4 +155,9 @@ o2physics_add_dpl_workflow(dedx-pid-analysis PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(pikp-raa-analysis + SOURCES piKpRAA.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + endif() diff --git a/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx b/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx index c710fce3735..13d063d2d82 100644 --- a/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx +++ b/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx @@ -256,6 +256,10 @@ struct AntinucleiInJets { // Generated spectra of antiprotons registryMC.add("antiproton_gen_jet", "antiproton_gen_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_gen_ue", "antiproton_gen_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Normalization histogram + registryMC.add("antiproton_deltay_deltaphi_jet", "antiproton_deltay_deltaphi_jet", HistType::kTH2F, {{2000, -1.0, 1.0, "#Delta#it{y}"}, {2000, 0.0, 2.0, "#Delta#phi"}}); + registryMC.add("antiproton_deltay_deltaphi_ue", "antiproton_deltay_deltaphi_ue", HistType::kTH2F, {{2000, -1.0, 1.0, "#Delta#it{y}"}, {2000, 0.0, 2.0, "#Delta#phi"}}); } // Reconstructed antiproton spectra in jets and UE (MC-matched) with TPC/TOF PID @@ -1459,6 +1463,9 @@ struct AntinucleiInJets { if (particle.eta() < minEta || particle.eta() > maxEta) continue; + // Fill normalization histogram + registryMC.fill(HIST("antiproton_deltay_deltaphi_jet"), particle.eta() - jet.eta(), getDeltaPhi(particle.phi(), jet.phi())); + // Fill histogram for generated antiprotons registryMC.fill(HIST("antiproton_gen_jet"), particle.pt()); } @@ -1491,6 +1498,14 @@ struct AntinucleiInJets { if (deltaRUe1 > maxConeRadius && deltaRUe2 > maxConeRadius) continue; + // Fill normalization histogram + if (deltaRUe1 < maxConeRadius) { + registryMC.fill(HIST("antiproton_deltay_deltaphi_ue"), protonVec.Eta() - ueAxis1.Eta(), getDeltaPhi(protonVec.Phi(), ueAxis1.Phi())); + } + if (deltaRUe2 < maxConeRadius) { + registryMC.fill(HIST("antiproton_deltay_deltaphi_ue"), protonVec.Eta() - ueAxis2.Eta(), getDeltaPhi(protonVec.Phi(), ueAxis2.Phi())); + } + // Fill histogram for antiprotons in the UE registryMC.fill(HIST("antiproton_gen_ue"), protonVec.Pt()); } diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index d688f0c8e72..2d042bd5e96 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -79,7 +79,7 @@ struct DedxPidAnalysis { Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; - Configurable maxDCAz{"maxDCAz", 2.f, "maxDCAz"}; + Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; Configurable minimumV0Radius{"minimumV0Radius", 0.5f, @@ -201,11 +201,11 @@ struct DedxPidAnalysis { // pt vs p registryDeDx.add( - "hp_vs_pt_all_Neg", "p_vs_pT", HistType::kTH2F, - {{ptAxis}, {pAxis}}); + "heta_vs_p_vs_pt_all_Neg", "eta_vs_p_vs_pT", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); registryDeDx.add( - "hp_vs_pt_all_Pos", "p_vs_pT", HistType::kTH2F, - {{ptAxis}, {pAxis}}); + "heta_vs_p_vs_pt_all_Pos", "eta_vs_p_vs_pT", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); // De/Dx for ch and v0 particles for (int i = 0; i < kParticlesType; ++i) { @@ -596,19 +596,8 @@ struct DedxPidAnalysis { if (!collision.sel8()) return; - if (additionalCuts) { - if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) - return; - - if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) - return; - - if (std::abs(collision.posZ()) >= maxZDistanceToIP) - return; - - if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) - return; - } + if (std::abs(collision.posZ()) > maxZDistanceToIP) + return; // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); @@ -624,8 +613,10 @@ struct DedxPidAnalysis { continue; // phi and Ncl cut - if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (additionalCuts) { + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } float signedP = trk.sign() * trk.tpcInnerParam(); @@ -704,10 +695,10 @@ struct DedxPidAnalysis { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - registryDeDx.fill(HIST("hp_vs_pt_all_Pos"), trk.pt(), signedP); + registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Pos"), trk.eta(), trk.pt(), signedP); } else { registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - registryDeDx.fill(HIST("hp_vs_pt_all_Neg"), trk.pt(), std::abs(signedP)); + registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Neg"), trk.eta(), trk.pt(), std::abs(signedP)); } } } @@ -736,11 +727,13 @@ struct DedxPidAnalysis { if (!negTrack.passedTPCRefit()) continue; // phi and Ncl cut - if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (additionalCuts) { + if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; - if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); diff --git a/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx b/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx index 78edc84586b..fc99ebcd30b 100644 --- a/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx +++ b/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx @@ -67,25 +67,25 @@ constexpr double kBetheBlochDefault[nParticles][nBetheParams]{ {5.393020, 7.859534, 0.004048, 2.323197, 1.609307, 0.09}, // triton {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}, // helion {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}}; // alpha -const int nTrkSettings = 14; -static const std::vector trackPIDsettingsNames{"useBBparams", "minITSnCls", "minITSnClscos", "minTPCnCls", "maxTPCchi2", "minTPCchi2", "maxITSchi2", "maxTPCnSigma", "maxDcaXY", "maxDcaZ", "minITSclsSize", "maxITSclsSize", "minTPCnClsCrossedRows", "minReqClusterITSib"}; +const int nTrkSettings = 13; +static const std::vector trackPIDsettingsNames{"useBBparams", "minITSnCls", "minITSnClscos", "minTPCnCls", "maxTPCchi2", "minTPCchi2", "maxITSchi2", "maxTPCnSigma", "maxDcaXY", "maxDcaZ", "minITSclsSize", "minTPCnClsCrossedRows", "minReqClusterITSib"}; constexpr double kTrackPIDSettings[nParticles][nTrkSettings]{ - {0, 0, 4, 60, 4.0, 0.5, 100, 2.5, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 75, 4.0, 0.5, 100, 5.0, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 5.0, 2., 2., 0., 1000, 70, 1}}; + {0, 0, 4, 60, 4.0, 0.5, 100, 2.5, 2., 2., 0., 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 70, 1}, + {1, 0, 4, 75, 4.0, 0.5, 100, 5.0, 2., 2., 0., 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 5.0, 2., 2., 0., 70, 1}}; -const int nTrkSettings2 = 4; -static const std::vector trackPIDsettingsNames2{"useITSnsigma", "minITSnsigma", "maxITSnsigma", "fillsparsh"}; +const int nTrkSettings2 = 6; +static const std::vector trackPIDsettingsNames2{"useITSnsigma", "minITSnsigma", "maxITSnsigma", "fillsparsh", "useTPCnsigmaTOF", "maxTPCnsigmaTOF"}; constexpr double kTrackPIDSettings2[nParticles][nTrkSettings2]{ - {1, -5, 4, 0}, - {1, -5, 4, 0}, - {1, -5, 4, 0}, - {1, -5, 4, 1}, - {1, -5, 4, 1}, - {1, -5, 4, 1}}; + {1, -5, 4, 0, 1, 2}, + {1, -5, 4, 0, 1, 2}, + {1, -5, 4, 0, 1, 2}, + {1, -5, 4, 1, 1, 2}, + {1, -5, 4, 1, 1, 2}, + {1, -5, 4, 1, 1, 2}}; struct PrimParticles { TString name; @@ -104,6 +104,7 @@ struct PrimParticles { }; // struct PrimParticles //---------------------------------------------------------------------------------------------------------------- std::vector> hmass; +std::vector> hmassnsigma; } // namespace //---------------------------------------------------------------------------------------------------------------- struct NucleitpcPbPb { @@ -142,7 +143,6 @@ struct NucleitpcPbPb { Configurable cfgminGetMeanItsClsSizeRequire{"cfgminGetMeanItsClsSizeRequire", true, "Require minGetMeanItsClsSize Cut"}; Configurable cfgmaxGetMeanItsClsSizeRequire{"cfgmaxGetMeanItsClsSizeRequire", true, "Require maxGetMeanItsClsSize Cut"}; Configurable cfgDCAwithptRequire{"cfgDCAwithptRequire", true, "Require DCA cuts with pt dependance"}; - Configurable cfgDCAnopt{"cfgDCAnopt", true, "Require DCA cuts without pt dependance"}; Configurable cfgRequirebetaplot{"cfgRequirebetaplot", true, "Require beta plot"}; Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {kBetheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; @@ -150,18 +150,17 @@ struct NucleitpcPbPb { Configurable> cfgTrackPIDsettings2{"cfgTrackPIDsettings2", {kTrackPIDSettings2[0], nParticles, nTrkSettings2, particleNames, trackPIDsettingsNames2}, "track selection and PID criteria"}; Configurable cfgFillhspectra{"cfgFillhspectra", true, "fill data sparsh"}; Configurable cfgFillmass{"cfgFillmass", false, "Fill mass histograms"}; + Configurable cfgFillmassnsigma{"cfgFillmassnsigma", true, "Fill mass vs nsigma histograms"}; Configurable centcut{"centcut", 80.0f, "centrality cut"}; Configurable cfgCutRapidity{"cfgCutRapidity", 0.5f, "Rapidity range"}; Configurable cfgZvertex{"cfgZvertex", 10, "Min Z Vertex"}; Configurable cfgZvertexRequire{"cfgZvertexRequire", true, "Pos Z cut require"}; Configurable cfgZvertexRequireMC{"cfgZvertexRequireMC", true, "Pos Z cut require for generated particles"}; Configurable cfgsel8Require{"cfgsel8Require", true, "sel8 cut require"}; - Configurable cfgtpcNClsFound{"cfgtpcNClsFound", 100.0f, "min. no. of tpcNClsFound"}; - Configurable cfgitsNCls{"cfgitsNCls", 2.0f, "min. no. of itsNCls"}; o2::track::TrackParametrizationWithError mTrackParCov; // Binning configuration ConfigurableAxis axisMagField{"axisMagField", {10, -10., 10.}, "magnetic field"}; - ConfigurableAxis axisNev{"axisNev", {3, 0., 3.}, "Number of events"}; + ConfigurableAxis axisNev{"axisNev", {5, 0., 5.}, "Number of events"}; ConfigurableAxis axisRigidity{"axisRigidity", {4000, -10., 10.}, "#it{p}^{TPC}/#it{z}"}; ConfigurableAxis axisdEdx{"axisdEdx", {4000, 0, 4000}, "d#it{E}/d#it{x}"}; ConfigurableAxis axisCent{"axisCent", {100, 0, 100}, "centrality"}; @@ -171,13 +170,9 @@ struct NucleitpcPbPb { ConfigurableAxis axiseta{"axiseta", {100, -1, 1}, "eta"}; ConfigurableAxis axisrapidity{"axisrapidity", {100, -2, 2}, "rapidity"}; ConfigurableAxis axismass{"axismass", {100, -10, 10}, "mass^{2}"}; - ConfigurableAxis nsigmaAxis{"nsigmaAxis", {160, -20, 20}, "n#sigma_{#pi^{+}}"}; + ConfigurableAxis nsigmaAxis{"nsigmaAxis", {160, -10, 10}, "n#sigma_{#pi^{+}}"}; ConfigurableAxis speciesBitAxis{"speciesBitAxis", {8, -0.5, 7.5}, "particle type 0: pion, 1: proton, 2: deuteron, 3: triton, 4:He3, 5:He4"}; ConfigurableAxis axisDCA{"axisDCA", {400, -10., 10.}, "DCA axis"}; - ConfigurableAxis axisTPCcls{"axisTPCcls", {400, 0., 200.}, "TPCcls axis"}; - ConfigurableAxis axisITScls{"axisITScls", {400, 0., 200.}, "ITScls axis"}; - ConfigurableAxis axisITSchi2{"axisITSchi2", {400, 0., 100.}, "ITSchi2 axis"}; - ConfigurableAxis axisTPCchi2{"axisTPCchi2", {400, 0., 100.}, "TPCchi2 axis"}; // CCDB Service ccdb; @@ -224,6 +219,7 @@ struct NucleitpcPbPb { histos.add("Tpcsignal", "Tpcsignal", kTH2F, {axisRigidity, axisdEdx}); hmass.resize(2 * nParticles + 2); + hmassnsigma.resize(2 * nParticles + 2); for (int i = 0; i < nParticles; i++) { TString histName = primaryParticles[i].name; @@ -232,8 +228,15 @@ struct NucleitpcPbPb { hmass[2 * i + 1] = histos.add(Form("histmass_ptanti/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); } } + for (int i = 0; i < nParticles; i++) { + TString histName = primaryParticles[i].name; + if (cfgFillmassnsigma) { + hmassnsigma[2 * i] = histos.add(Form("histmass_nsigma/histmass_%s", histName.Data()), ";nsigma; mass^{2}", HistType::kTH2F, {nsigmaAxis, axismass}); + hmassnsigma[2 * i + 1] = histos.add(Form("histmass_nsigmaanti/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {nsigmaAxis, axismass}); + } + } - histos.add("hSpectra", " ", HistType::kTHnSparseF, {speciesBitAxis, ptAxis, nsigmaAxis, {5, -2.5, 2.5}, axisCent, axisRigidity, axisdEdx, axisDCA, axisDCA, nsigmaAxis}); + histos.add("hSpectra", " ", HistType::kTHnSparseF, {speciesBitAxis, ptAxis, nsigmaAxis, {5, -2.5, 2.5}, axisCent, axisDCA, axisDCA, axisrapidity, axiseta}); if (doprocessMC) { histomc.add("histVtxZgen", "histVtxZgen", kTH1F, {axisVtxZ}); @@ -253,8 +256,11 @@ struct NucleitpcPbPb { histomc.add("histPtRecoHe4", "histPtgenHe4", kTH1F, {ptAxis}); histomc.add("histPtRecoAntiHe4", "histPtgenAntiHe4", kTH1F, {ptAxis}); histomc.add("histDeltaPtVsPtGen", " delta pt vs pt rec", HistType::kTH2F, {{1000, 0, 10}, {1000, -0.5, 0.5, "p_{T}(reco) - p_{T}(gen);p_{T}(reco)"}}); + histomc.add("histDeltaPtVsPtGenanti", " delta pt vs pt rec", HistType::kTH2F, {{1000, 0, 10}, {1000, -0.5, 0.5, "p_{T}(reco) - p_{T}(gen);p_{T}(reco)"}}); histomc.add("histPIDtrack", " delta pt vs pt rec", HistType::kTH2F, {{1000, 0, 10, "p_{T}(reco)"}, {9, -0.5, 8.5, "p_{T}(reco) - p_{T}(gen)"}}); + histomc.add("histPIDtrackanti", " delta pt vs pt rec", HistType::kTH2F, {{1000, 0, 10, "p_{T}(reco)"}, {9, -0.5, 8.5, "p_{T}(reco) - p_{T}(gen)"}}); histomc.add("histDeltaPtVsPtGenHe4", " delta pt vs pt rec", HistType::kTH2F, {{1000, 0, 10}, {1000, -0.5, 0.5, "p_{T}(reco) - p_{T}(gen);p_{T}(reco)"}}); + histomc.add("histDeltaPtVsPtGenHe4anti", " delta pt vs pt rec", HistType::kTH2F, {{1000, 0, 10}, {1000, -0.5, 0.5, "p_{T}(reco) - p_{T}(gen);p_{T}(reco)"}}); } } //---------------------------------------------------------------------------------------------------------------- @@ -309,7 +315,7 @@ struct NucleitpcPbPb { } if (track.sign() < 0) { sign = -1; - } // <- This redeclares a new local variable! + } if (std::abs(getRapidity(track, i)) > cfgCutRapidity && cfgRapidityRequire) continue; if (track.tpcNClsFound() < cfgTrackPIDsettings->get(i, "minTPCnCls") && cfgTPCNClsfoundRequire) @@ -331,8 +337,6 @@ struct NucleitpcPbPb { continue; if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize") && cfgminGetMeanItsClsSizeRequire) continue; - if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize") && cfgmaxGetMeanItsClsSizeRequire) - continue; bool insideDCAxy = (std::abs(track.dcaXY()) <= (cfgTrackPIDsettings->get(i, "maxDcaXY") * (0.0105f + 0.0350f / std::pow(ptMomn, 1.1f)))); // o2-linter: disable=magic-number (To be checked) if ((!(insideDCAxy) || std::abs(track.dcaZ()) > dcazSigma(ptMomn, cfgTrackPIDsettings->get(i, "maxDcaZ"))) && cfgDCAwithptRequire) @@ -342,23 +346,24 @@ struct NucleitpcPbPb { if ((std::abs(tpcNsigma) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) && cfgmaxTPCnSigmaRequire) continue; float itsSigma = getITSnSigma(track, primaryParticles.at(i)); - if (itsSigma < cfgTrackPIDsettings2->get(i, "minITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) continue; if (itsSigma > cfgTrackPIDsettings2->get(i, "maxITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) continue; + histos.fill(HIST("Tpcsignal"), getRigidity(track) * track.sign(), track.tpcSignal()); - fillhmass(track, i); if (cfgFillhspectra && cfgTrackPIDsettings2->get(i, "fillsparsh") == 1) { - histos.fill(HIST("hSpectra"), i, ptMomn, tpcNsigma, sign, collision.centFT0C(), getRigidity(track) * track.sign(), track.tpcSignal(), track.dcaZ(), track.dcaXY(), itsSigma); + histos.fill(HIST("hSpectra"), i, ptMomn, tpcNsigma, sign, collision.centFT0C(), track.dcaZ(), track.dcaXY(), getRapidity(track, i), track.eta()); } + fillhmassnsigma(track, i, tpcNsigma); + if ((std::abs(tpcNsigma) > cfgTrackPIDsettings2->get(i, "maxTPCnsigmaTOF")) && cfgTrackPIDsettings2->get(i, "useTPCnsigmaTOF") < 1) + continue; + fillhmass(track, i); + if (cfgRequirebetaplot) { histos.fill(HIST("Tofsignal"), getRigidity(track) * track.sign(), o2::pid::tof::Beta::GetBeta(track)); } } - if (track.tpcNClsFound() > cfgtpcNClsFound || track.itsNCls() > cfgitsNCls) { - histos.fill(HIST("Tpcsignal"), getRigidity(track) * track.sign(), track.tpcSignal()); - } histos.fill(HIST("histeta"), track.eta()); } // track loop /////////////////////////////////////////////// @@ -420,7 +425,6 @@ struct NucleitpcPbPb { if (std::abs(collision.posZ()) > cfgZvertex && cfgZvertexRequire) continue; collPassedEvSel = collision.sel8(); - occupancy = collision.trackOccupancyInTimeRange(); if (!collPassedEvSel && cfgsel8Require) continue; histomc.fill(HIST("histNevReco"), 1.5); @@ -429,6 +433,7 @@ struct NucleitpcPbPb { histomc.fill(HIST("histCentFT0MReco"), collision.centFT0M()); if (collision.centFT0C() > centcut) continue; + histomc.fill(HIST("histNevReco"), 2.5); if (removeITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) continue; if (removeNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) @@ -478,7 +483,7 @@ struct NucleitpcPbPb { } if (track.sign() < 0) { sign = -1; - } // <- This redeclares a new local variable! + } if (std::abs(getRapidity(track, i)) > cfgCutRapidity && cfgRapidityRequire) continue; if (track.tpcNClsFound() < cfgTrackPIDsettings->get(i, "minTPCnCls") && cfgTPCNClsfoundRequire) @@ -500,8 +505,6 @@ struct NucleitpcPbPb { continue; if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize") && cfgminGetMeanItsClsSizeRequire) continue; - if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize") && cfgmaxGetMeanItsClsSizeRequire) - continue; bool insideDCAxy = (std::abs(track.dcaXY()) <= (cfgTrackPIDsettings->get(i, "maxDcaXY") * (0.0105f + 0.0350f / std::pow(ptMomn, 1.1f)))); // o2-linter: disable=magic-number (To be checked) if ((!(insideDCAxy) || std::abs(track.dcaZ()) > dcazSigma(ptMomn, cfgTrackPIDsettings->get(i, "maxDcaZ"))) && cfgDCAwithptRequire) @@ -511,16 +514,20 @@ struct NucleitpcPbPb { if ((std::abs(tpcNsigma) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) && cfgmaxTPCnSigmaRequire) continue; float itsSigma = getITSnSigma(track, primaryParticles.at(i)); - if (itsSigma < cfgTrackPIDsettings2->get(i, "minITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) continue; if (itsSigma > cfgTrackPIDsettings2->get(i, "maxITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) continue; + histos.fill(HIST("Tpcsignal"), getRigidity(track) * track.sign(), track.tpcSignal()); - fillhmass(track, i); if (cfgFillhspectra && cfgTrackPIDsettings2->get(i, "fillsparsh") == 1) { - histos.fill(HIST("hSpectra"), i, ptMomn, tpcNsigma, sign, collision.centFT0C(), getRigidity(track) * track.sign(), track.tpcSignal(), track.dcaZ(), track.dcaXY(), itsSigma); + histos.fill(HIST("hSpectra"), i, ptMomn, tpcNsigma, sign, collision.centFT0C(), track.dcaZ(), track.dcaXY(), getRapidity(track, i), track.eta()); } + fillhmassnsigma(track, i, tpcNsigma); + if ((std::abs(tpcNsigma) > cfgTrackPIDsettings2->get(i, "maxTPCnsigmaTOF")) && cfgTrackPIDsettings2->get(i, "useTPCnsigmaTOF") < 1) + continue; + fillhmass(track, i); + if (cfgRequirebetaplot) { histos.fill(HIST("Tofsignal"), getRigidity(track) * track.sign(), o2::pid::tof::Beta::GetBeta(track)); } @@ -545,12 +552,21 @@ struct NucleitpcPbPb { float deltaPt = ptReco - ptGen; if (pdg == -particlePdgCodes.at(4)) { + histomc.fill(HIST("histDeltaPtVsPtGenanti"), ptReco, deltaPt); + histomc.fill(HIST("histPIDtrackanti"), ptReco, track.pidForTracking()); + } + if (pdg == particlePdgCodes.at(4)) { histomc.fill(HIST("histDeltaPtVsPtGen"), ptReco, deltaPt); histomc.fill(HIST("histPIDtrack"), ptReco, track.pidForTracking()); } + if (pdg == -particlePdgCodes.at(5)) { + histomc.fill(HIST("histDeltaPtVsPtGenHe4anti"), ptReco, deltaPt); + } + if (pdg == particlePdgCodes.at(5)) { histomc.fill(HIST("histDeltaPtVsPtGenHe4"), ptReco, deltaPt); } + if (pdg == particlePdgCodes.at(4)) { histomc.fill(HIST("histPtRecoHe3"), ptReco); } else if (pdg == -particlePdgCodes.at(4)) { @@ -628,14 +644,15 @@ struct NucleitpcPbPb { if (!track.hasTOF() || !cfgFillmass) return; float beta{o2::pid::tof::Beta::GetBeta(track)}; - if (beta <= 0.f || beta >= 1.f) + const float eps = 1e-6f; + if (beta < eps || beta > 1.0f - eps) return; float charge = (species == he3 || species == he4) ? 2.f : 1.f; float p = getRigidity(track); // assuming this is the momentum from inner TPC float massTOF = p * charge * std::sqrt(1.f / (beta * beta) - 1.f); // get PDG mass float pdgMass = particleMasses[species]; - float massDiff = massTOF - pdgMass; + float massDiff = massTOF * massTOF - pdgMass * pdgMass; float ptMomn; setTrackParCov(track, mTrackParCov); mTrackParCov.setPID(track.pidForTracking()); @@ -648,6 +665,29 @@ struct NucleitpcPbPb { } //---------------------------------------------------------------------------------------------------------------- template + void fillhmassnsigma(T const& track, int species, float sigma) + { + if (!track.hasTOF() || !cfgFillmassnsigma) + return; + float beta{o2::pid::tof::Beta::GetBeta(track)}; + const float eps = 1e-6f; + if (beta < eps || beta > 1.0f - eps) + return; + float charge = (species == he3 || species == he4) ? 2.f : 1.f; + float p = getRigidity(track); // assuming this is the momentum from inner TPC + float massTOF = p * charge * std::sqrt(1.f / (beta * beta) - 1.f); + // get PDG mass + float pdgMass = particleMasses[species]; + float massDiff = massTOF * massTOF - pdgMass * pdgMass; + + if (track.sign() > 0) { + hmassnsigma[2 * species]->Fill(sigma, massDiff); + } else if (track.sign() < 0) { + hmassnsigma[2 * species + 1]->Fill(sigma, massDiff); + } + } + //---------------------------------------------------------------------------------------------------------------- + template float getTPCnSigma(T const& track, PrimParticles& particle) { const float rigidity = getRigidity(track); diff --git a/PWGLF/Tasks/Nuspex/piKpRAA.cxx b/PWGLF/Tasks/Nuspex/piKpRAA.cxx new file mode 100644 index 00000000000..1fb44ccd448 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/piKpRAA.cxx @@ -0,0 +1,1135 @@ +// 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 piKpRAA.cxx +/// +/// \brief task for analysis of piKp RAA +/// \author Omar Vazquez (omar.vazquez.rueda@cern.ch) +/// \since August 10, 2025 + +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/ZDCConstants.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" // required for Filter op. +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" +#include "ReconstructionDataFormats/Track.h" +#include + +#include "TPDGCode.h" +#include "TVector3.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod::evsel; +using namespace o2::constants::math; +using namespace o2::framework::expressions; + +using ColEvSels = soa::Join; +using BCsRun3 = soa::Join; +// using TracksFull = soa::Join; + +using TracksFull = soa::Join; + +static constexpr int kNEtaHists{4}; + +std::array, kNEtaHists> dEdxPiV0{}; +std::array, kNEtaHists> dEdxPrV0{}; +std::array, kNEtaHists> dEdxElV0{}; +std::array, kNEtaHists> dEdxPiTOF{}; + +struct PiKpRAA { + + static constexpr float kZero{0.0f}; + static constexpr float kOne{1.0f}; + static constexpr float kTenToMinusNine{1e-9}; + static constexpr float kMinPtNchSel{0.1f}; + static constexpr float kMaxPtNchSel{3.0f}; + static constexpr float kMinCharge{3.f}; + static constexpr float kMinPElMIP{0.3f}; + static constexpr float kMaxPElMIP{0.4f}; + static constexpr float kMinPMIP{0.4f}; + static constexpr float kMaxPMIP{0.6f}; + static constexpr float kMindEdxMIP{40.0f}; + static constexpr float kMaxdEdxMIP{60.0f}; + static constexpr float kMindEdxMIPPlateau{70.0f}; + static constexpr float kMaxdEdxMIPPlateau{90.0f}; + + // static constexpr float kLowEta[kNEtaHists] = {-0.8, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6}; + // static constexpr float kHighEta[kNEtaHists] = {0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + static constexpr float kLowEta[kNEtaHists] = {0.0, 0.2, 0.4, 0.6}; + static constexpr float kHighEta[kNEtaHists] = {0.2, 0.4, 0.6, 0.8}; + + static constexpr float DefaultLifetimeCuts[1][2] = {{30., 20.}}; + Configurable> lifetimecut{"lifetimecut", {DefaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; + + struct : ConfigurableGroup { + Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; + + // Selection criteria: acceptance + Configurable rapidityCut{"rapidityCut", 0.5, "rapidity"}; + Configurable minEtaDaughter{"minEtaDaughter", -0.8, "Daughter minimum-eta selection"}; + Configurable maxEtaDaughter{"maxEtaDaughter", +0.8, "Daughter maximum-eta selection"}; + Configurable minPt{"minPt", 0.15, "minimum pt of the tracks"}; + Configurable maxPt{"maxPt", 20.0, "maximum pt of the tracks"}; + Configurable minNclFound{"minNclFound", 135, "minimum found Ncl in TPC"}; + + // Standard 5 topological criteria + Configurable v0cospa{"v0cospa", 0.995, "min V0 CosPA"}; + Configurable dcav0dau{"dcav0dau", 1.0, "max DCA V0 Daughters (cm)"}; + Configurable dcanegtopv{"dcanegtopv", .1, "min DCA Neg To PV (cm)"}; + Configurable dcapostopv{"dcapostopv", .1, "min DCA Pos To PV (cm)"}; + Configurable v0radius{"v0radius", 1.2, "minimum V0 radius (cm)"}; + Configurable v0radiusMax{"v0radiusMax", 1E5, "maximum V0 radius (cm)"}; + + // Additional selection on the AP plot (exclusive for K0Short) + // original equation: lArmPt*5>TMath::Abs(lArmAlpha) + Configurable armPodCut{"armPodCut", 5.0f, "pT * (cut) > |alpha|, AP cut. Negative: no cut"}; + Configurable armAlphaSel{"armAlphaSel", 0.45f, "Armenteros alpha selection (Gammas)"}; + Configurable qTSel{"qTSel", 0.1f, "Armenteros qT select (Gammas)"}; + + // Selection + Configurable applyInvMassSel{"applyInvMassSel", false, "Select V0s close to the Inv. mass value"}; + Configurable dMassSel{"dMassSel", 0.01f, "Invariant mass selection"}; + Configurable dMassSelG{"dMassSelG", 0.1f, "Inv mass selection gammas"}; + + // PID (TPC/TOF) + Configurable tpcPidNsigmaCut{"tpcPidNsigmaCut", 5, "tpcPidNsigmaCut"}; + Configurable maxPiTOFBeta{"maxPiTOFBeta", 0.00005, "Maximum beta TOF selection"}; + Configurable maxElTOFBeta{"maxElTOFBeta", 0.1, "Maximum beta TOF selection"}; + Configurable applyTPCTOFCombinedCut{"applyTPCTOFCombinedCut", false, " Apply geometrical cut ? "}; + + // Phi cut + Configurable applyPhiCut{"applyPhiCut", false, "Apply geometrical cut?"}; + Configurable applyEtaCal{"applyEtaCal", false, "Apply eta calibration?"}; + Configurable usePinPhiSelection{"usePinPhiSelection", true, "Uses Phi selection as a function of P or Pt?"}; + Configurable applyNclSel{"applyNclSel", false, "Apply Min. found Ncl in TPC?"}; + } v0Selections; + + // Configurables Event Selection + Configurable isNoCollInTimeRangeStrict{"isNoCollInTimeRangeStrict", true, "use isNoCollInTimeRangeStrict?"}; + Configurable isNoCollInTimeRangeStandard{"isNoCollInTimeRangeStandard", false, "use isNoCollInTimeRangeStandard?"}; + Configurable isNoCollInRofStrict{"isNoCollInRofStrict", true, "use isNoCollInRofStrict?"}; + Configurable isNoCollInRofStandard{"isNoCollInRofStandard", false, "use isNoCollInRofStandard?"}; + Configurable isNoHighMultCollInPrevRof{"isNoHighMultCollInPrevRof", true, "use isNoHighMultCollInPrevRof?"}; + Configurable isNoCollInTimeRangeNarrow{"isNoCollInTimeRangeNarrow", false, "use isNoCollInTimeRangeNarrow?"}; + Configurable isOccupancyCut{"isOccupancyCut", true, "Occupancy cut?"}; + Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "T0C Occu cut"}; + Configurable applyNchSel{"applyNchSel", false, "Use mid-rapidity-based Nch selection"}; + Configurable skipRecoColGTOne{"skipRecoColGTOne", true, "Remove collisions if reconstructed more than once"}; + Configurable detector4Calibration{"detector4Calibration", "T0M", "Detector for nSigma-Nch rejection"}; + + // Event selection + Configurable posZcut{"posZcut", +10.0, "z-vertex position cut"}; + Configurable minT0CcentCut{"minT0CcentCut", 0.0, "Min T0C Cent. cut"}; + Configurable maxT0CcentCut{"maxT0CcentCut", 100.0, "Max T0C Cent. cut"}; + Configurable minOccCut{"minOccCut", 0., "min Occu cut"}; + Configurable maxOccCut{"maxOccCut", 500., "max Occu cut"}; + Configurable nSigmaNchCut{"nSigmaNchCut", 3., "nSigma Nch selection"}; + + ConfigurableAxis binsPtPhiCut{"binsPtPhiCut", {VARIABLE_WIDTH, 0.0, 0.6, 0.8, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0, 3.5, 4.0, 5.0, 7.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 45.0, 50.0}, "pT"}; + ConfigurableAxis binsPtV0s{"binsPtV0s", {VARIABLE_WIDTH, 0, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3.0, 3.5, 4, 5, 7, 9, 12, 15, 20}, "pT"}; + ConfigurableAxis binsPtNcl{"binsPtNcl", {VARIABLE_WIDTH, 0.0, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.0, 9.0, 12.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0}, "pT"}; + ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.12}, "pT binning"}; + ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.}, "T0C binning"}; + ConfigurableAxis axisArmAlpha{"axisArmAlpha", {200, -1.0, 1.0}, "Armenteros alpha"}; + ConfigurableAxis axisArmqT{"axisArmqT", {200, 0.0f, 0.3f}, "Armenteros qT"}; + ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, "Mass K0Short"}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, "Mass Lambda"}; + ConfigurableAxis axisGammaMass{"axisGammaMass", {200, 0.0f, 0.5f}, "Mass Gamma"}; + ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {200, -10.0f, 10.0f}, "N sigma TPC"}; + ConfigurableAxis axisdEdx{"axisdEdx", {140, 20.0, 160.0}, "dEdx binning"}; + Configurable nBinsNch{"nBinsNch", 400, "N bins Nch (|eta|<0.8)"}; + Configurable nBinsNPV{"nBinsNPV", 600, "N bins ITS tracks"}; + Configurable minNch{"minNch", 0, "Min Nch (|eta|<0.8)"}; + Configurable maxNch{"maxNch", 400, "Max Nch (|eta|<0.8)"}; + Configurable minNpv{"minNpv", 0, "Min NPV"}; + Configurable maxNpv{"maxNpv", 600, "Max NPV"}; + + // CCDB paths + Configurable pathMeanNch{"pathMeanNch", "Users/o/omvazque/MeanNch/OO/Pass2/PerTimeStamp/Aug20", "base path to the ccdb object"}; + Configurable pathSigmaNch{"pathSigmaNch", "Users/o/omvazque/SigmaNch/OO/Pass2/PerTimeStamp/Aug20", "base path to the ccdb object"}; + Configurable pathEtaCal{"pathEtaCal", "Users/o/omvazque/EtaCal/OO/Global", "base path to the ccdb object"}; + Configurable pathPhiCutHigh{"pathPhiCutHigh", "Users/o/omvazque/PhiCut/OO/Global/High", "base path to the ccdb object"}; + Configurable pathPhiCutLow{"pathPhiCutLow", "Users/o/omvazque/PhiCut/OO/Global/Low", "base path to the ccdb object"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + + enum EvCutLabel { + All = 1, + SelEigth, + NoSameBunchPileup, + IsGoodZvtxFT0vsPV, + NoCollInTimeRangeStrict, + NoCollInTimeRangeStandard, + NoCollInRofStrict, + NoCollInRofStandard, + NoHighMultCollInPrevRof, + NoCollInTimeRangeNarrow, + OccuCut, + Centrality, + VtxZ, + NchSel + }; + + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + Service ccdb; + + struct ConfigNch { + TH1F* hMeanNch = nullptr; + TH1F* hSigmaNch = nullptr; + bool calibrationsLoaded = false; + } cfgNch; + + struct ConfigPhiCut { + TH1F* hPhiCutHigh = nullptr; + TH1F* hPhiCutLow = nullptr; + bool isPhiCutLoaded = false; + } phiCut; + + struct ConfigEtaCalib { + TProfile* pEtaCal = nullptr; + bool isCalLoaded = false; + } etaCal; + + TrackSelection trkSelDaugthers; + TrackSelection trkSelGlobal; + TrackSelection trkSelDaugthersV0s() + { + TrackSelection selectedTracks; + selectedTracks.SetEtaRange(-0.8f, 0.8f); + selectedTracks.SetMinNCrossedRowsTPC(70); + return selectedTracks; + } + + int currentRunNumberNchSel; + int currentRunNumberPhiSel; + void init(InitContext const&) + { + currentRunNumberNchSel = -1; + currentRunNumberPhiSel = -1; + trkSelDaugthers = trkSelDaugthersV0s(); + trkSelGlobal = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + + // define axes you want to use + const std::string titlePorPt{v0Selections.usePinPhiSelection ? "#it{p} (GeV/#it{c})" : "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisZpos{48, -12., 12., "Vtx_{z} (cm)"}; + const AxisSpec axisEvent{15, 0.5, 15.5, ""}; + const AxisSpec axisEta{100, -1., +1., "#eta"}; + const AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisPtV0s{binsPtV0s, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisXNcl{binsPtNcl, Form("%s", titlePorPt.data())}; + const AxisSpec axisXPhiCut{binsPtPhiCut, Form("%s", titlePorPt.data())}; + const AxisSpec axisCent{binsCent, "T0C centrality"}; + const char* endingEta[kNEtaHists] = {"02", "24", "46", "68"}; + const char* latexEta[kNEtaHists] = {"0<|#eta|<0.2", "0.2<#eta<0.4", "0.4<#eta<0.6", "0.6<#eta<0.8"}; + + registry.add("EventCounter", ";;Events", kTH1F, {axisEvent}); + + auto hstat = registry.get(HIST("EventCounter")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "All"); + x->SetBinLabel(2, "SelEigth"); + x->SetBinLabel(3, "NoSameBunchPileup"); + x->SetBinLabel(4, "GoodZvtxFT0vsPV"); + x->SetBinLabel(5, "NoCollInTimeRangeStrict"); + x->SetBinLabel(6, "NoCollInTimeRangeStandard"); + x->SetBinLabel(7, "NoCollInRofStrict"); + x->SetBinLabel(8, "NoCollInRofStandard"); + x->SetBinLabel(9, "NoHighMultCollInPrevRof"); + x->SetBinLabel(10, "NoCollInTimeRangeNarrow"); + x->SetBinLabel(11, "Occupancy Cut"); + x->SetBinLabel(12, "Cent. Sel."); + x->SetBinLabel(13, "VtxZ Sel."); + x->SetBinLabel(14, "Nch Sel."); + + if (doprocessCalibrationAndV0s) { + registry.add("zPos", ";;Entries;", kTH1F, {axisZpos}); + registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); + registry.add("NchVsNPV", ";Nch; NPV;", kTH2F, {{{nBinsNPV, minNpv, maxNpv}, {nBinsNch, minNch, maxNch}}}); + registry.add("ExcludedEvtVsNch", ";Nch;Entries;", kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("ExcludedEvtVsNPV", ";NPV;Entries;", kTH1F, {{nBinsNPV, minNpv, maxNpv}}); + + registry.add("dcaDauVsPt", ";V0 #it{p}_{T} (GeV/#it{c});DCA_{xy} (cm) daughters;", kTH2F, {{{axisPtV0s}, {200, -10., 10.}}}); + registry.add("nSigPiFromK0s", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); + registry.add("nSigPiFromL", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); + registry.add("nSigPrFromL", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); + registry.add("nSigPiFromAL", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); + registry.add("nSigPrFromAL", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); + registry.add("nSigElFromG", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); + registry.add("ArmAll", "Armenteros-Podolanski;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("ArmAfterTopoSel", "Armenteros-Podolanski anfter topological selection;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("ArmK0NOSel", "Armenteros-Podolanski WITH OUT 5 #times q_{T} > #alpha selection;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("ArmK0", "Armenteros-Podolanski WITH 5 #times q_{T} > #alpha selection;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("ArmL", "Armenteros-Podolanski;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("ArmAL", "Armenteros-Podolanski;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("ArmG", "Armenteros-Podolanski;#alpha;q_{T} (GeV/c)", kTH2F, {axisArmAlpha, axisArmqT}); + registry.add("MassK0sVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisK0Mass}); + registry.add("MassLVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisLambdaMass}); + registry.add("MassALVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisLambdaMass}); + registry.add("MassGVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisGammaMass}); + + registry.add("NclFindable", ";;Findable Ncl TPC", kTH2F, {{{axisXNcl}, {161, -0.5, 160.5}}}); + registry.add("NclFindablep", ";;Findable #LTNcl#GT TPC", kTProfile, {axisXNcl}); + registry.add("NclFound", ";;Found Ncl TPC", kTH2F, {{{axisXNcl}, {161, -0.5, 160.5}}}); + registry.add("NclFoundp", ";;Found #LTNcl#GT TPC", kTProfile, {axisXNcl}); + registry.add("NclFoundVsPhipBeforeCut", Form("Found #LTNcl#GT TPC;%s (GeV/#it{c});#varphi", titlePorPt.data()), kTProfile2D, {{{axisXPhiCut}, {350, 0.0, 0.35}}}); + registry.add("NclFoundVsPhipAfterCut", Form("Found #LTNcl#GT TPC;%s (GeV/#it{c});#varphi", titlePorPt.data()), kTProfile2D, {{{axisXPhiCut}, {350, 0.0, 0.35}}}); + registry.add("NclVsEta", ";#eta; Ncl TPC", kTH2F, {{{axisEta}, {161, -0.5, 160.5}}}); + + registry.add("NclVsEtaPiMIP", "MIP #pi^{+} + #pi^{-} (0.4 < #it{p} < 0.6 GeV/#it{c}, 40 < dE/dx < 60);#eta; Found Ncl TPC", kTH2F, {{{axisEta}, {161, -0.5, 160.5}}}); + registry.add("NclVsEtaPiMIPp", "MIP #pi^{+} + #pi^{-} (0.4 < #it{p} < 0.6 GeV/#it{c}, 40 < dE/dx < 60);#eta; Found #LTNcl#GT TPC", kTProfile, {axisEta}); + registry.add("NclVsEtaPiV0", ";#eta; Found Ncl TPC", kTH2F, {{{axisEta}, {161, -0.5, 160.5}}}); + registry.add("NclVsEtaPiV0p", ";#eta; Found #LTNcl#GT TPC", kTProfile, {axisEta}); + registry.add("NclPiV0", ";;Found Ncl TPC", kTH2F, {{{axisXNcl}, {161, -0.5, 160.5}}}); + registry.add("NclPiV0p", ";;Found #LTNcl#GT TPC", kTProfile, {axisXNcl}); + registry.add("NclVsEtaPrV0", ";#eta; Found Ncl TPC", kTH2F, {{{axisEta}, {161, -0.5, 160.5}}}); + registry.add("NclVsEtaPrV0p", ";#eta; Found #LTNcl#GT TPC", kTProfile, {axisEta}); + registry.add("NclPrV0", ";;Found Ncl TPC", kTH2F, {{{axisXNcl}, {161, -0.5, 160.5}}}); + registry.add("NclPrV0p", ";;Found #LTNcl#GT TPC", kTProfile, {axisXNcl}); + registry.add("NclVsEtaElV0", ";#eta; Found Ncl TPC", kTH2F, {{{axisEta}, {161, -0.5, 160.5}}}); + registry.add("NclVsEtaElV0p", ";#eta; Found #LTNcl#GT TPC", kTProfile, {axisEta}); + registry.add("NclElV0", ";;Found Ncl TPC", kTH2F, {{{axisXNcl}, {161, -0.5, 160.5}}}); + registry.add("NclElV0p", ";;Found #LTNcl#GT TPC", kTProfile, {axisXNcl}); + + registry.add("TOFExpPi2TOF", ";Momentum (GeV/#it{c});t^{e}_{Exp}/t_{TOF}", kTH2F, {{{axisPtV0s}, {100, 0.2, 1.2}}}); + registry.add("TOFExpEl2TOF", ";Momentum (GeV/#it{c});t^{#pi}_{Exp}/t_{TOF}", kTH2F, {{{axisPtV0s}, {100, 0.2, 1.2}}}); + + registry.add("betaVsMomentum", ";Momentum (GeV/#it{c}); #beta", kTH2F, {{{axisPtV0s}, {500, 0, 1.2}}}); + registry.add("dEdxVsMomentum", ";Momentum (GeV/#it{c}); dE/dx", kTH2F, {axisPtV0s, axisdEdx}); + registry.add("dEdxVsEtaPiMIP", "MIP #pi^{+} + #pi^{-} (0.4 < #it{p} < 0.6 GeV/#it{c});#eta; dE/dx;", kTH2F, {{{axisEta}, {100, 0, 100}}}); + registry.add("dEdxVsEtaPiMIPp", "MIP #pi^{+} + #pi^{-} (0.4 < #it{p} < 0.6 GeV/#it{c});#eta; #LTdE/dx#GT", kTProfile, {axisEta}); + registry.add("dEdxVsEtaElMIP", "MIP e^{+} + e^{-} (0.3 < #it{p} < 0.4 GeV/#it{c});#eta; dE/dx;", kTH2F, {{{axisEta}, {100, 0, 100}}}); + registry.add("dEdxVsEtaElMIPp", "MIP e^{+} + e^{-} (0.3 < #it{p} < 0.4 GeV/#it{c});#eta; #LTdE/dx#GT", kTProfile, {axisEta}); + registry.add("dEdxVsEtaPiMIPV0", "MIP #pi^{+} + #pi^{-} (0.4 < #it{p} < 0.6 GeV/#it{c});#eta; dE/dx", kTH2F, {{{axisEta}, {100, 0, 100}}}); + registry.add("dEdxVsEtaPiMIPV0p", "MIP #pi^{+} + #pi^{-} (0.4 < #it{p} < 0.6 GeV/#it{c});#eta; #LTdE/dx#GT", kTProfile, {axisEta}); + registry.add("dEdxVsEtaElMIPV0", "e^{+} + e^{-} (0.4 < #it{p} < 0.6 GeV/#it{c});#eta; dE/dx", kTH2F, {{{axisEta}, {100, 0, 100}}}); + registry.add("dEdxVsEtaElMIPV0p", "e^{+} + e^{-} (0.4 < #it{p} < 0.6 GeV/#it{c});#eta; #LTdE/dx#GT", kTProfile, {axisEta}); + + for (int i = 0; i < kNEtaHists; ++i) { + dEdxPiV0[i] = registry.add(Form("dEdxPiV0_%s", endingEta[i]), Form("#pi^{+} + #pi^{-}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH3F, {axisPtV0s, axisdEdx, axisCent}); + dEdxPrV0[i] = registry.add(Form("dEdxPrV0_%s", endingEta[i]), Form("p + #bar{p}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH3F, {axisPtV0s, axisdEdx, axisCent}); + dEdxElV0[i] = registry.add(Form("dEdxElV0_%s", endingEta[i]), Form("e^{+} + e^{-}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH3F, {axisPtV0s, axisdEdx, axisCent}); + dEdxPiTOF[i] = registry.add(Form("dEdxPiTOF_%s", endingEta[i]), Form("#pi^{+} + #pi^{-}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH3F, {axisPtV0s, axisdEdx, axisCent}); + } + } + + LOG(info) << "\tccdbNoLaterThan=" << ccdbNoLaterThan.value; + LOG(info) << "\tapplyNchSel=" << applyNchSel.value; + LOG(info) << "\tdetector4Calibration=" << detector4Calibration.value; + LOG(info) << "\tminPt=" << v0Selections.minPt; + LOG(info) << "\tmaxPt=" << v0Selections.maxPt; + LOG(info) << "\tapplyTPCTOFCombinedCut=" << v0Selections.applyTPCTOFCombinedCut; + LOG(info) << "\tapplyInvMassSel=" << v0Selections.applyInvMassSel; + LOG(info) << "\tapplyNclSel=" << v0Selections.applyNclSel; + LOG(info) << "\tapplyPhiCut=" << v0Selections.applyPhiCut; + LOG(info) << "\tusePinPhiSelection=" << v0Selections.usePinPhiSelection; + LOG(info) << "\ttitlePorPt=" << titlePorPt; + LOG(info) << "\tcurrentRunNumberNchSel=" << currentRunNumberNchSel; + LOG(info) << "\tcurrentRunNumberPhiSel=" << currentRunNumberPhiSel; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); + + if (applyNchSel.value) { + LOG(info) << "\tLoading Nch-based selections!"; + LOG(info) << "\t pathMeanNch=" << pathMeanNch.value; + LOG(info) << "\t pathSigmaNch=" << pathSigmaNch.value; + } + + if (v0Selections.applyPhiCut) { + LOG(info) << "\tLoading Phi cut!"; + LOG(info) << "\t pathPhiCutLow=" << pathPhiCutLow.value; + LOG(info) << "\t pathPhiCutHigh=" << pathPhiCutHigh.value; + } + + if (v0Selections.applyEtaCal) { + LOG(info) << "\tLoading Eta Cal!"; + LOG(info) << "\t pathEtaCal=" << pathEtaCal.value; + loadEtaCalibration(); + } + + if (v0Selections.applyNclSel) + LOG(info) << "\t minNclFound=" << v0Selections.minNclFound; + } + + void processCalibrationAndV0s(ColEvSels::iterator const& collision, BCsRun3 const& /**/, aod::V0Datas const& v0s, aod::FV0As const& /**/, aod::FT0s const& /**/, TracksFull const& tracks) + { + // LOG(info) << " Collisions size: " << collisions.size() << " + // Table's size: " << collisions.tableSize() << "\n"; + // LOG(info) << "Run number: " << foundBC.runNumber() << "\n"; + if (!isEventSelected(collision)) { + return; + } + + const auto& foundBC = collision.foundBC_as(); + const uint64_t timeStamp{foundBC.timestamp()}; + const int magField{getMagneticField(timeStamp)}; + const double nPV{collision.multNTracksPVeta1() / 1.}; + + if (applyNchSel) { + const int nextRunNumber{foundBC.runNumber()}; + if (currentRunNumberNchSel != nextRunNumber) { + loadNchCalibrations(timeStamp); + currentRunNumberNchSel = nextRunNumber; + LOG(info) << "\tcurrentRunNumberNchSel= " << currentRunNumberNchSel << " timeStamp = " << timeStamp; + } + + // return if Nch selection objects are nullptr + if (!(cfgNch.hMeanNch && cfgNch.hSigmaNch)) + return; + } + + int nch{0}; + for (const auto& track : tracks) { + // Track Selection + if (!trkSelGlobal.IsSelected(track)) { + continue; + } + if (track.pt() < kMinPtNchSel || track.pt() > kMaxPtNchSel) { + continue; + } + nch++; + } + + bool skipEvent{false}; + if (applyNchSel) { + if (!cfgNch.calibrationsLoaded) + return; + + const double xEval{nPV}; + const int bin4Calibration{cfgNch.hMeanNch->FindBin(xEval)}; + const double meanNch{cfgNch.hMeanNch->GetBinContent(bin4Calibration)}; + const double sigmaNch{cfgNch.hSigmaNch->GetBinContent(bin4Calibration)}; + const double nSigmaSelection{nSigmaNchCut * sigmaNch}; + const double diffMeanNch{meanNch - nch}; + + if (std::abs(diffMeanNch) > nSigmaSelection) { + registry.fill(HIST("ExcludedEvtVsNch"), nch); + registry.fill(HIST("ExcludedEvtVsNPV"), nPV); + skipEvent = true; + } + } + + if (applyNchSel && skipEvent) { + return; + } + + if (applyNchSel) + registry.fill(HIST("EventCounter"), EvCutLabel::NchSel); + + registry.fill(HIST("NchVsNPV"), nPV, nch); + registry.fill(HIST("zPos"), collision.posZ()); + registry.fill(HIST("T0Ccent"), collision.centFT0C()); + const float centrality{collision.centFT0C()}; + + if (v0Selections.applyPhiCut) { + const int nextRunNumber{foundBC.runNumber()}; + if (currentRunNumberPhiSel != nextRunNumber) { + loadPhiCutSelections(timeStamp); + currentRunNumberPhiSel = nextRunNumber; + LOG(info) << "\tcurrentRunNumberPhiSel= " << currentRunNumberPhiSel << " timeStamp = " << timeStamp; + } + + // return if phi cut objects are nullptr + if (!(phiCut.hPhiCutHigh && phiCut.hPhiCutLow)) + return; + } + + for (const auto& track : tracks) { + + if (!trkSelGlobal.IsSelected(track)) + continue; + + if (track.pt() < v0Selections.minPt || track.pt() > v0Selections.maxPt) + continue; + + const float momentum{track.p()}; + const float pt{track.pt()}; + const float phi{track.phi()}; + const float eta{track.eta()}; + float dedx{track.tpcSignal()}; + const int charge{track.sign()}; + const float pOrPt{v0Selections.usePinPhiSelection ? momentum : pt}; + const int16_t nclFound{track.tpcNClsFound()}; + + if (v0Selections.applyNclSel && nclFound < v0Selections.minNclFound) + continue; + + float phiPrime{phi}; + phiPrimeFunc(phiPrime, magField, charge); + registry.fill(HIST("NclFoundVsPhipBeforeCut"), pOrPt, phiPrime, track.tpcNClsFound()); + + if (v0Selections.applyPhiCut) { + if (!passesPhiSelection(pOrPt, phiPrime)) + continue; + } + + if (v0Selections.applyEtaCal) { + const double dedxCal{etaCal.pEtaCal->GetBinContent(etaCal.pEtaCal->FindBin(eta))}; + if (dedxCal > kMindEdxMIP && dedxCal < kMaxdEdxMIP) + dedx *= (50.0 / dedxCal); + else + continue; + } + + if (momentum > kMinPMIP && momentum < kMaxPMIP && dedx > kMindEdxMIP && dedx < kMaxdEdxMIP) { + registry.fill(HIST("dEdxVsEtaPiMIP"), eta, dedx); + registry.fill(HIST("dEdxVsEtaPiMIPp"), eta, dedx); + registry.fill(HIST("NclVsEtaPiMIP"), eta, track.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiMIPp"), eta, track.tpcNClsFound()); + } + + if (momentum > kMinPElMIP && momentum < kMaxPElMIP && dedx > kMindEdxMIPPlateau && dedx < kMaxdEdxMIPPlateau) { + registry.fill(HIST("dEdxVsEtaElMIP"), eta, dedx); + registry.fill(HIST("dEdxVsEtaElMIPp"), eta, dedx); + } + + registry.fill(HIST("dEdxVsMomentum"), momentum, dedx); + registry.fill(HIST("NclVsEta"), eta, track.tpcNClsFound()); + registry.fill(HIST("NclFound"), pOrPt, track.tpcNClsFound()); + registry.fill(HIST("NclFoundp"), pOrPt, track.tpcNClsFound()); + registry.fill(HIST("NclFindable"), pOrPt, track.tpcNClsFindable()); + registry.fill(HIST("NclFindablep"), pOrPt, track.tpcNClsFindable()); + registry.fill(HIST("NclFoundVsPhipAfterCut"), pOrPt, phiPrime, track.tpcNClsFound()); + + int indexEta{0}; + for (int i = 1; i < kNEtaHists; ++i) { + if (std::abs(eta) >= kLowEta[i] && std::abs(eta) < kHighEta[i]) { + indexEta = i; + break; + } + } + + if (track.hasTOF() && track.goodTOFMatch()) { + const float tTOF{track.tofSignal()}; + const float trkLength{track.length()}; + const float tExpPiTOF{track.tofExpSignalPi(tTOF)}; + const float tExpElTOF{track.tofExpSignalEl(tTOF)}; + // const float dTOFPi{tTOF - tExpPiTOF - colTime}; + // const float dTOFEl{tTOF - tExpElTOF - colTime}; + + if (trkLength > kZero && tTOF > kZero) { + registry.fill(HIST("betaVsMomentum"), momentum, track.beta()); + registry.fill(HIST("TOFExpPi2TOF"), momentum, tExpPiTOF / tTOF); + registry.fill(HIST("TOFExpEl2TOF"), momentum, tExpElTOF / tTOF); + + if (std::abs((tExpPiTOF / tTOF) - kOne) < v0Selections.maxPiTOFBeta) { + dEdxPiTOF[indexEta]->Fill(momentum, dedx, centrality); + } + } + } + } + + for (const auto& v0 : v0s) { + + // Select V0 type + if (v0.v0Type() != v0Selections.v0TypeSelection) + continue; + + // Positive-(negative-)charged tracks (daughters) + const auto& posTrack = v0.posTrack_as(); + const auto& negTrack = v0.negTrack_as(); + const int posTrackCharge{posTrack.sign()}; + const int negTrackCharge{negTrack.sign()}; + const float posTrkP{posTrack.p()}; + const float negTrkP{negTrack.p()}; + const float posTrkPt{posTrack.pt()}; + const float negTrkPt{negTrack.pt()}; + const float posTrkEta{posTrack.eta()}; + const float negTrkEta{negTrack.eta()}; + float posTrkdEdx{posTrack.tpcSignal()}; + float negTrkdEdx{negTrack.tpcSignal()}; + float posTrackPhiPrime{posTrack.phi()}; + float negTrackPhiPrime{negTrack.phi()}; + const int16_t posNclFound{posTrack.tpcNClsFound()}; + const int16_t negNclFound{negTrack.tpcNClsFound()}; + phiPrimeFunc(posTrackPhiPrime, magField, posTrackCharge); + phiPrimeFunc(negTrackPhiPrime, magField, negTrackCharge); + const float posPorPt{v0Selections.usePinPhiSelection ? posTrkP : posTrkPt}; + const float negPorPt{v0Selections.usePinPhiSelection ? negTrkP : negTrkPt}; + + // Skip v0s with like-sig daughters + if (posTrack.sign() == negTrack.sign()) + continue; + + // Passes Geometrical (Phi) cut? + if (v0Selections.applyPhiCut) { + if (!(passesPhiSelection(posPorPt, posTrackPhiPrime) && passesPhiSelection(negPorPt, negTrackPhiPrime))) + continue; + } + + // Passes daughters track-selection? + if (!(passesTrackSelectionDaughters(posTrack) && passesTrackSelectionDaughters(negTrack))) + continue; + + if (v0Selections.applyNclSel && (posNclFound < v0Selections.minNclFound || negNclFound < v0Selections.minNclFound)) + continue; + + if (v0Selections.applyEtaCal) { + const double dedxCal{etaCal.pEtaCal->GetBinContent(etaCal.pEtaCal->FindBin(posTrkEta))}; + if (dedxCal > kMindEdxMIP && dedxCal < kMaxdEdxMIP) + posTrkdEdx *= (50.0 / dedxCal); + else + continue; + } + + if (v0Selections.applyEtaCal) { + const double dedxCal{etaCal.pEtaCal->GetBinContent(etaCal.pEtaCal->FindBin(negTrkEta))}; + if (dedxCal > kMindEdxMIP && dedxCal < kMaxdEdxMIP) + negTrkdEdx *= (50.0 / dedxCal); + else + continue; + } + + const TVector3 ppos(posTrack.px(), posTrack.py(), posTrack.pz()); + const TVector3 pneg(negTrack.px(), negTrack.py(), negTrack.pz()); + double alpha, qT; + + getArmeterosVariables(ppos, pneg, alpha, qT); + registry.fill(HIST("ArmAll"), alpha, qT); + + // Passes V0 topological cuts? + if (!passesV0TopologicalSelection(v0)) + continue; + + const double dMassK0s{std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short)}; + const double dMassL{std::abs(v0.mLambda() - o2::constants::physics::MassLambda0)}; + const double dMassAL{std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0)}; + const double dMassG{std::abs(v0.mGamma() - o2::constants::physics::MassGamma)}; + + registry.fill(HIST("ArmAfterTopoSel"), alpha, qT); + registry.fill(HIST("dcaDauVsPt"), v0.pt(), v0.dcapostopv()); + registry.fill(HIST("dcaDauVsPt"), v0.pt(), v0.dcanegtopv()); + + int posIndexEta{0}; + int negIndexEta{0}; + for (int i = 1; i < kNEtaHists; ++i) { + if (std::abs(posTrkEta) >= kLowEta[i] && std::abs(posTrkEta) < kHighEta[i]) { + posIndexEta = i; + break; + } + } + + for (int i = 1; i < kNEtaHists; ++i) { + if (std::abs(negTrkEta) >= kLowEta[i] && std::abs(negTrkEta) < kHighEta[i]) { + negIndexEta = i; + break; + } + } + + if (v0Selections.applyInvMassSel) { // apply Inv. Mass selection? + if (dMassK0s < v0Selections.dMassSel && dMassL > v0Selections.dMassSel && dMassAL > v0Selections.dMassSel && dMassG > v0Selections.dMassSelG) { // Mass cut + if (passesK0Selection(collision, v0)) { // nSigma TPC and y cuts + registry.fill(HIST("ArmK0NOSel"), alpha, qT); + if (v0Selections.armPodCut * qT > std::abs(alpha)) { // Armenters selection + registry.fill(HIST("ArmK0"), alpha, qT); + registry.fill(HIST("MassK0sVsPt"), v0.pt(), v0.mK0Short()); + registry.fill(HIST("nSigPiFromK0s"), posTrkPt, posTrack.tpcNSigmaPi()); + registry.fill(HIST("nSigPiFromK0s"), negTrkPt, negTrack.tpcNSigmaPi()); + registry.fill(HIST("NclVsEtaPiV0"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiV0p"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiV0"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiV0p"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0p"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0"), negPorPt, negTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0p"), negPorPt, negTrack.tpcNClsFound()); + + dEdxPiV0[posIndexEta]->Fill(posTrkP, posTrkdEdx, centrality); + dEdxPiV0[negIndexEta]->Fill(negTrkP, negTrkdEdx, centrality); + + if (posTrkP > kMinPMIP && posTrkP < kMaxPMIP && posTrkdEdx > kMindEdxMIP && posTrkdEdx < kMaxdEdxMIP) { + registry.fill(HIST("dEdxVsEtaPiMIPV0"), posTrkEta, posTrkdEdx); + registry.fill(HIST("dEdxVsEtaPiMIPV0p"), posTrkEta, posTrkdEdx); + } + if (negTrkP > kMinPMIP && negTrkP < kMaxPMIP && negTrkdEdx > kMindEdxMIP && negTrkdEdx < kMaxdEdxMIP) { + registry.fill(HIST("dEdxVsEtaPiMIPV0"), negTrkEta, negTrkdEdx); + registry.fill(HIST("dEdxVsEtaPiMIPV0p"), negTrkEta, negTrkdEdx); + } + } + } + } + } + + if (v0Selections.applyInvMassSel) { + if (dMassL < v0Selections.dMassSel && dMassK0s > v0Selections.dMassSel && dMassG > v0Selections.dMassSelG) { + if (passesLambdaSelection(collision, v0)) { + registry.fill(HIST("ArmL"), alpha, qT); + registry.fill(HIST("MassLVsPt"), v0.pt(), v0.mLambda()); + registry.fill(HIST("nSigPrFromL"), posTrkPt, posTrack.tpcNSigmaPr()); + registry.fill(HIST("nSigPiFromL"), negTrkPt, negTrack.tpcNSigmaPi()); + registry.fill(HIST("NclVsEtaPrV0"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPrV0p"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiV0"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiV0p"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclPrV0"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclPrV0p"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0"), negPorPt, negTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0p"), negPorPt, negTrack.tpcNClsFound()); + dEdxPrV0[posIndexEta]->Fill(posTrkP, posTrkdEdx, centrality); + dEdxPiV0[negIndexEta]->Fill(negTrkP, negTrkdEdx, centrality); + } + } + } + + if (v0Selections.applyInvMassSel && dMassAL < v0Selections.dMassSel && dMassK0s > v0Selections.dMassSel && dMassG > v0Selections.dMassSelG) { + if (passesAntiLambdaSelection(collision, v0)) { + registry.fill(HIST("ArmAL"), alpha, qT); + registry.fill(HIST("MassALVsPt"), v0.pt(), v0.mAntiLambda()); + registry.fill(HIST("nSigPrFromAL"), negTrkPt, negTrack.tpcNSigmaPr()); + registry.fill(HIST("nSigPiFromAL"), posTrkPt, posTrack.tpcNSigmaPi()); + registry.fill(HIST("NclVsEtaPiV0"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPiV0p"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPrV0"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPrV0p"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclPiV0p"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclPrV0"), negPorPt, negTrack.tpcNClsFound()); + registry.fill(HIST("NclPrV0p"), negPorPt, negTrack.tpcNClsFound()); + dEdxPrV0[negIndexEta]->Fill(negTrkP, negTrkdEdx, centrality); + dEdxPiV0[posIndexEta]->Fill(posTrkP, posTrkdEdx, centrality); + } + } + + if (v0Selections.applyInvMassSel && dMassK0s > v0Selections.dMassSel && dMassL > v0Selections.dMassSel && dMassAL > v0Selections.dMassSel && dMassG < v0Selections.dMassSel) { + if (passesGammaSelection(collision, v0)) { + if (std::abs(alpha) < v0Selections.armAlphaSel && qT < v0Selections.qTSel) { + registry.fill(HIST("ArmG"), alpha, qT); + registry.fill(HIST("MassGVsPt"), v0.pt(), v0.mGamma()); + registry.fill(HIST("nSigElFromG"), negTrkPt, negTrack.tpcNSigmaEl()); + registry.fill(HIST("nSigElFromG"), posTrkPt, posTrack.tpcNSigmaEl()); + registry.fill(HIST("NclVsEtaElV0"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaElV0p"), posTrkEta, posTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaElV0"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclVsEtaElV0p"), negTrkEta, negTrack.tpcNClsFound()); + registry.fill(HIST("NclElV0"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclElV0p"), posPorPt, posTrack.tpcNClsFound()); + registry.fill(HIST("NclElV0"), negPorPt, negTrack.tpcNClsFound()); + registry.fill(HIST("NclElV0p"), negPorPt, negTrack.tpcNClsFound()); + registry.fill(HIST("dEdxVsEtaElMIPV0"), posTrkEta, posTrkdEdx); + registry.fill(HIST("dEdxVsEtaElMIPV0p"), posTrkEta, posTrkdEdx); + registry.fill(HIST("dEdxVsEtaElMIPV0"), negTrkEta, negTrkdEdx); + registry.fill(HIST("dEdxVsEtaElMIPV0p"), negTrkEta, negTrkdEdx); + dEdxElV0[posIndexEta]->Fill(posTrkP, posTrkdEdx, centrality); + dEdxElV0[negIndexEta]->Fill(negTrkP, negTrkdEdx, centrality); + } + } + } + } + } + PROCESS_SWITCH(PiKpRAA, processCalibrationAndV0s, "Process QA", true); + + template + void getArmeterosVariables(const T& ppos, const T& pneg, U& alpha, U& qT) + { + + alpha = 0., qT = 0.; + TVector3 pV0 = ppos + pneg; + double pV0mag = pV0.Mag(); + if (pV0mag < kTenToMinusNine) + return; // protect against zero momentum + + const TVector3 u = pV0 * (1.0 / pV0mag); + + double pLpos = ppos.Dot(u); + double pLneg = pneg.Dot(u); + + // qT: transverse momentum of the + track w.r.t. V0 direction + TVector3 pTpos = ppos - pLpos * u; + qT = pTpos.Mag(); + + // α: longitudinal asymmetry (uses + and − labels by charge) + double denom = pLpos + pLneg; + if (std::abs(denom) < kTenToMinusNine) + return; // avoid 0 division (unphysical for V0s) + + alpha = (pLpos - pLneg) / denom; // equivalently / pV0mag + } + + // Daughters DCA selection + template + bool passesDCASelectionDaughters(const T& v0) + { + + bool isSelected{false}; + // const double ptPos{std::sqrt(std::pow(v0.pxpos(), 2.0) + std::pow(v0.pypos(), 2.0))}; + // const double ptNeg{std::sqrt(std::pow(v0.pxneg(), 2.0) + std::pow(v0.pyneg(), 2.0))}; + // const double dcaPtDepPos{0.0105 + 0.035 * std::pow(ptPos, -1.1)}; + // const double dcaPtDepNeg{0.0105 + 0.035 * std::pow(ptNeg, -1.1)}; + // const double dcaSelPos = std::max(0.1, dcaPtDepPos); + // const double dcaSelNeg = std::max(0.1, dcaPtDepNeg); + + const double dcaPos{std::fabs(v0.dcapostopv())}; + const double dcaNeg{std::fabs(v0.dcanegtopv())}; + + isSelected = dcaPos > v0Selections.dcapostopv && dcaNeg > v0Selections.dcanegtopv ? true : false; + return isSelected; + } + + template + bool passesTrackSelectionDaughters(const T& track) + { + + bool isSelected = trkSelDaugthers.IsSelected(track) ? true : false; + + return isSelected; + } + + // V0 topological selection + template + bool passesV0TopologicalSelection(const T& v0) + { + + bool isSelected = v0.v0radius() > v0Selections.v0radius && v0.v0radius() < v0Selections.v0radiusMax && passesDCASelectionDaughters(v0) && v0.v0cosPA() > v0Selections.v0cospa && v0.dcaV0daughters() < v0Selections.dcav0dau ? true : false; + + return isSelected; + } + + template + bool passesK0Selection(const C& collision, const T& v0) + { + // Selection on rapiditty, proper lifetime, and Nsigma Pion + + const auto& posTrack = v0.template posTrack_as(); + const auto& negTrack = v0.template negTrack_as(); + + const float posTPCNsigma{std::fabs(posTrack.tpcNSigmaPi())}; + const float negTPCNsigma{std::fabs(negTrack.tpcNSigmaPi())}; + const float posTOFNsigma{std::fabs(posTrack.tofNSigmaPi())}; + const float negTOFNsigma{std::fabs(negTrack.tofNSigmaPi())}; + const double posRadiusNsigma{std::sqrt(std::pow(posTPCNsigma, 2.) + std::pow(posTOFNsigma, 2.))}; + const double negRadiusNsigma{std::sqrt(std::pow(negTPCNsigma, 2.) + std::pow(negTOFNsigma, 2.))}; + + bool isSelected{false}; + if (v0Selections.applyTPCTOFCombinedCut) + isSelected = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S") && std::abs(v0.yK0Short()) < v0Selections.rapidityCut && posTrack.hasTOF() && negTrack.hasTOF() && posRadiusNsigma < v0Selections.tpcPidNsigmaCut && negRadiusNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + else + isSelected = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S") && std::abs(v0.yK0Short()) < v0Selections.rapidityCut && posTPCNsigma < v0Selections.tpcPidNsigmaCut && negTPCNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + + return isSelected; + } + + template + bool passesLambdaSelection(const C& collision, const T& v0) + { + // Selection on rapiditty, proper lifetime, and Nsigma Pion + + const auto& posTrack = v0.template posTrack_as(); + const auto& negTrack = v0.template negTrack_as(); + + const float posTPCNsigma{std::fabs(posTrack.tpcNSigmaPr())}; + const float negTPCNsigma{std::fabs(negTrack.tpcNSigmaPi())}; + const float posTOFNsigma{std::fabs(posTrack.tofNSigmaPr())}; + const float negTOFNsigma{std::fabs(negTrack.tofNSigmaPi())}; + const double posRadiusNsigma{std::sqrt(std::pow(posTPCNsigma, 2.) + std::pow(posTOFNsigma, 2.))}; + const double negRadiusNsigma{std::sqrt(std::pow(negTPCNsigma, 2.) + std::pow(negTOFNsigma, 2.))}; + + bool isSelected{false}; + if (v0Selections.applyTPCTOFCombinedCut) + isSelected = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda") && std::abs(v0.yLambda()) < v0Selections.rapidityCut && posTrack.hasTOF() && negTrack.hasTOF() && posRadiusNsigma < v0Selections.tpcPidNsigmaCut && negRadiusNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + else + isSelected = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda") && std::abs(v0.yLambda()) < v0Selections.rapidityCut && posTPCNsigma < v0Selections.tpcPidNsigmaCut && negTPCNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + + return isSelected; + } + + template + bool passesAntiLambdaSelection(const C& collision, const T& v0) + { + // Selection on rapiditty, proper lifetime, and Nsigma Pion + + const auto& posTrack = v0.template posTrack_as(); + const auto& negTrack = v0.template negTrack_as(); + + const float posTPCNsigma{std::fabs(posTrack.tpcNSigmaPi())}; + const float negTPCNsigma{std::fabs(negTrack.tpcNSigmaPr())}; + const float posTOFNsigma{std::fabs(posTrack.tofNSigmaPi())}; + const float negTOFNsigma{std::fabs(negTrack.tofNSigmaPr())}; + const double posRadiusNsigma{std::sqrt(std::pow(posTPCNsigma, 2.) + std::pow(posTOFNsigma, 2.))}; + const double negRadiusNsigma{std::sqrt(std::pow(negTPCNsigma, 2.) + std::pow(negTOFNsigma, 2.))}; + + bool isSelected{false}; + if (v0Selections.applyTPCTOFCombinedCut) + isSelected = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda") && std::abs(v0.yLambda()) < v0Selections.rapidityCut && posTrack.hasTOF() && negTrack.hasTOF() && posRadiusNsigma < v0Selections.tpcPidNsigmaCut && negRadiusNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + else + isSelected = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda") && std::abs(v0.yLambda()) < v0Selections.rapidityCut && posTPCNsigma < v0Selections.tpcPidNsigmaCut && negTPCNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + + return isSelected; + } + + template + bool passesGammaSelection(const C& /*collision*/, const T& v0) + { + const auto& posTrack = v0.template posTrack_as(); + const auto& negTrack = v0.template negTrack_as(); + + const float posTPCNsigma{std::fabs(posTrack.tpcNSigmaEl())}; + const float negTPCNsigma{std::fabs(negTrack.tpcNSigmaEl())}; + const float posTOFNsigma{std::fabs(posTrack.tofNSigmaEl())}; + const float negTOFNsigma{std::fabs(negTrack.tofNSigmaEl())}; + const double posRadiusNsigma{std::sqrt(std::pow(posTPCNsigma, 2.) + std::pow(posTOFNsigma, 2.))}; + const double negRadiusNsigma{std::sqrt(std::pow(negTPCNsigma, 2.) + std::pow(negTOFNsigma, 2.))}; + const float yGamma = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma); + + if (!(std::abs(yGamma) < v0Selections.rapidityCut)) + return false; + + bool isSelected{false}; + if (v0Selections.applyTPCTOFCombinedCut) + isSelected = posTrack.hasTOF() && negTrack.hasTOF() && posRadiusNsigma < v0Selections.tpcPidNsigmaCut && negRadiusNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + else + isSelected = posTPCNsigma < v0Selections.tpcPidNsigmaCut && negTPCNsigma < v0Selections.tpcPidNsigmaCut ? true : false; + + return isSelected; + } + + int getMagneticField(uint64_t timestamp) + { + // TODO done only once (and not per run). Will be replaced by CCDBConfigurable + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + void phiPrimeFunc(float& phi, const int& magField, const int& charge) + { + + if (magField < 0) + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) + phi = o2::constants::math::TwoPI - phi; + + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + } + + bool passesPhiSelection(const float& pt, const float& phi) + { + + bool isSelected{false}; + if (phiCut.isPhiCutLoaded) { + const int binLow{phiCut.hPhiCutLow->FindBin(pt)}; + const int binHigh{phiCut.hPhiCutHigh->FindBin(pt)}; + const double phiCutLow{phiCut.hPhiCutLow->GetBinContent(binLow)}; + const double phiCutHigh{phiCut.hPhiCutHigh->GetBinContent(binHigh)}; + if (phi < phiCutLow || phi > phiCutHigh) + isSelected = true; + } + return isSelected; + } + + template + bool isEventSelected(CheckCol const& col) + { + registry.fill(HIST("EventCounter"), EvCutLabel::All); + if (!col.sel8()) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::SelEigth); + + if (!col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoSameBunchPileup); + + if (!col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::IsGoodZvtxFT0vsPV); + + if (isNoCollInTimeRangeStrict) { + if (!col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoCollInTimeRangeStrict); + } + + if (isNoCollInTimeRangeStandard) { + if (!col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoCollInTimeRangeStandard); + } + + if (isNoCollInRofStrict) { + if (!col.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoCollInRofStrict); + } + + if (isNoCollInRofStandard) { + if (!col.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoCollInRofStandard); + } + + if (isNoHighMultCollInPrevRof) { + if (!col.selection_bit( + o2::aod::evsel::kNoHighMultCollInPrevRof)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoHighMultCollInPrevRof); + } + + // To be used in combination with FT0C-based occupancy + if (isNoCollInTimeRangeNarrow) { + if (!col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::NoCollInTimeRangeNarrow); + } + + if (isOccupancyCut) { + auto occuValue{isApplyFT0CbasedOccupancy ? col.ft0cOccupancyInTimeRange() : col.trackOccupancyInTimeRange()}; + if (occuValue < minOccCut || occuValue > maxOccCut) { + return false; + } + } + registry.fill(HIST("EventCounter"), EvCutLabel::OccuCut); + + if (col.centFT0C() < minT0CcentCut || col.centFT0C() > maxT0CcentCut) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::Centrality); + + // Z-vertex position cut + if (std::fabs(col.posZ()) > posZcut) { + return false; + } + registry.fill(HIST("EventCounter"), EvCutLabel::VtxZ); + + return true; + } + + template + void getPTpowers(const T& pTs, const T& vecEff, const T& vecFD, U& pOne, + U& wOne, U& pTwo, U& wTwo, U& pThree, U& wThree, + U& pFour, U& wFour) + { + pOne = wOne = pTwo = wTwo = pThree = wThree = pFour = wFour = 0.; + for (std::size_t i = 0; i < pTs.size(); ++i) { + const double pTi{pTs.at(i)}; + const double eFFi{vecEff.at(i)}; + const double fDi{vecFD.at(i)}; + const double wEighti{std::pow(eFFi, -1.) * fDi}; + pOne += wEighti * pTi; + wOne += wEighti; + pTwo += std::pow(wEighti * pTi, 2.); + wTwo += std::pow(wEighti, 2.); + pThree += std::pow(wEighti * pTi, 3.); + wThree += std::pow(wEighti, 3.); + pFour += std::pow(wEighti * pTi, 4.); + wFour += std::pow(wEighti, 4.); + } + } + + void loadNchCalibrations(uint64_t timeStamp) + { + if (pathMeanNch.value.empty() == false) { + cfgNch.hMeanNch = ccdb->getForTimeStamp(pathMeanNch, timeStamp); + if (cfgNch.hMeanNch == nullptr) { + LOGF(fatal, "Could not load hMeanNch histogram from %s", pathMeanNch.value.c_str()); + } + } + + if (pathSigmaNch.value.empty() == false) { + cfgNch.hSigmaNch = ccdb->getForTimeStamp(pathSigmaNch, timeStamp); + if (cfgNch.hSigmaNch == nullptr) { + LOGF(fatal, "Could not load hSigmaNch histogram from %s", pathSigmaNch.value.c_str()); + } + } + if (cfgNch.hMeanNch && cfgNch.hSigmaNch) + cfgNch.calibrationsLoaded = true; + } + + void loadPhiCutSelections(const uint64_t& timeStamp) + { + + if (pathPhiCutHigh.value.empty() == false) { + phiCut.hPhiCutHigh = ccdb->getForTimeStamp(pathPhiCutHigh, timeStamp); + if (phiCut.hPhiCutHigh == nullptr) { + LOGF(fatal, "Could not load efficiency histogram from %s", pathPhiCutHigh.value.c_str()); + } + } + + if (pathPhiCutLow.value.empty() == false) { + phiCut.hPhiCutLow = ccdb->getForTimeStamp(pathPhiCutLow, timeStamp); + if (phiCut.hPhiCutLow == nullptr) { + LOGF(fatal, "Could not load efficiency histogram from %s", pathPhiCutLow.value.c_str()); + } + } + + if (phiCut.hPhiCutHigh && phiCut.hPhiCutLow) + phiCut.isPhiCutLoaded = true; + } + + void loadEtaCalibration() + { + if (pathEtaCal.value.empty() == false) { + etaCal.pEtaCal = ccdb->getForTimeStamp(pathEtaCal, ccdbNoLaterThan.value); + if (etaCal.pEtaCal == nullptr) { + LOGF(fatal, "Could not load pEtaCal from %s", pathEtaCal.value.c_str()); + } + } + + if (etaCal.pEtaCal) + etaCal.isCalLoaded = true; + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/QC/strangepidqa.cxx b/PWGLF/Tasks/QC/strangepidqa.cxx index 2dd9c58b4e7..08e502b87f5 100644 --- a/PWGLF/Tasks/QC/strangepidqa.cxx +++ b/PWGLF/Tasks/QC/strangepidqa.cxx @@ -51,22 +51,16 @@ struct strangepidqa { ConfigurableAxis vertexZ{"vertexZ", {30, -15.0f, 15.0f}, ""}; // base properties - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f}, "p_{T} (GeV/c)"}; ConfigurableAxis axisRadius{"axisRadius", {200, 0.0f, 100.0f}, "V0 radius (cm)"}; ConfigurableAxis centAxis{"centAxis", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 50.0f, 70.0f, 100.0f}, "FT0C centrality"}; - AxisSpec massAxisXi = {200, 1.222f, 1.422f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec massAxisOmega = {200, 1.572f, 1.772f, "Inv. Mass (GeV/c^{2})"}; - // Invariant Mass ConfigurableAxis axisK0ShortMass{"axisK0ShortMass", {200, 0.497f - 0.050f, 0.497f + 0.050f}, "M_{K0s} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.08f, 1.16f}, "M_{#Lambda} (GeV/c^{2})"}; - - // time axes - ConfigurableAxis axisDeltaTime{"axisDeltaTime", {200, -1000.0f, +1000.0f}, "#Delta time (ps)"}; - ConfigurableAxis axisTime{"axisTime", {200, 0.0f, +20000.0f}, "T (ps)"}; - ConfigurableAxis axisBeta{"axisBeta", {1200, 0.0f, +1.2f}, "#Beta"}; + AxisSpec massAxisXi = {200, 1.222f, 1.422f, "Inv. Mass (GeV/c^{2})"}; + AxisSpec massAxisOmega = {200, 1.572f, 1.772f, "Inv. Mass (GeV/c^{2})"}; // Length axis ConfigurableAxis axisLength{"axisLength", {600, 0.0f, +600.0f}, "track Length (cm)"}; @@ -74,24 +68,8 @@ struct strangepidqa { // TOF cut axis ConfigurableAxis axisTOFCut{"axisTOFCut", {100, 0.0f, +10000.0f}, "TOF compat. cut (ps)"}; - // TOF selection matters - Configurable requireTOFsignalPion{"requireTOFsignalPion", true, "require that pion prongs have TOF"}; - Configurable requireTOFsignalProton{"requireTOFsignalProton", true, "require that proton prongs have TOF"}; - Configurable requireTOFEventTimePion{"requireTOFEventTimePion", true, "require that pion prongs have TOF event time"}; - Configurable requireTOFEventTimeProton{"requireTOFEventTimeProton", true, "require that proton prongs have TOF event time"}; - - Configurable maxDeltaTimeProton{"maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; - Configurable maxDeltaTimePion{"maxDeltaTimePion", 1e+9, "check maximum allowed time"}; - Configurable maxDeltaTimeDecay{"maxDeltaTimeDecay", 1e+9, "check maximum allowed delta-time-decay"}; - - Configurable minCentrality{"minCentrality", 60, "max value of centrality allowed"}; - Configurable maxCentrality{"maxCentrality", 100, "max value of centrality allowed"}; - - Configurable minV0Radius{"minV0Radius", 1.5, "min radius"}; - Configurable minCosPA{"minCosPA", .98, "min cosPA"}; - - Configurable minPtV0{"minPtV0", 1.0, "min pT for integrated mass histograms"}; - Configurable maxPtV0{"maxPtV0", 3.0, "max pT for integrated mass histograms"}; + // nsigma axis + ConfigurableAxis axisNSigma{"axisNSigma", {60, -3.0f, +3.0f}, "NSigma"}; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* // Selection criteria for cascade analysis @@ -112,14 +90,9 @@ struct strangepidqa { Configurable tpcNsigmaBachelor{"tpcNsigmaBachelor", 4, "TPC NSigma bachelor (>10 is no cut)"}; Configurable tpcNsigmaProton{"tpcNsigmaProton", 4, "TPC NSigma proton <- lambda (>10 is no cut)"}; Configurable tpcNsigmaPion{"tpcNsigmaPion", 4, "TPC NSigma pion <- lambda (>10 is no cut)"}; - - Configurable tofNsigmaXiLaPr{"tpcNsigmaXiLaPr", 1e+5, "TOF NSigma proton <- lambda <- Xi (>10 is no cut)"}; - Configurable tofNsigmaXiLaPi{"tpcNsigmaXiLaPi", 1e+5, "TOF NSigma pion <- lambda <- Xi (>10 is no cut)"}; - Configurable tofNsigmaXiPi{"tpcNsigmaXiPi", 1e+5, "TOF NSigma pion <- Xi (>10 is no cut)"}; - Configurable tofNsigmaOmLaPr{"tpcNsigmaOmLaPr", 1e+5, "TOF NSigma proton <- lambda <- Omega (>10 is no cut)"}; - Configurable tofNsigmaOmLaPi{"tpcNsigmaOmLaPi", 1e+5, "TOF NSigma pion <- lambda <- Omega (>10 is no cut)"}; - Configurable tofNsigmaOmKa{"tpcNsigmaOmKa", 1e+5, "TOF NSigma Kaon <- Omega (>10 is no cut)"}; - + //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* + // Direct test configurables + Configurable massWindowForNSigmaPlots{"massWindowForNSigmaPlots", 0.005f, "mass window for Nsigma comparison plots"}; Configurable tofNsigmaCompatibility{"tofNsigmaCompatibility", 4, "compatibility check for V0s"}; Configurable tofNsigmaCompatibilityCascades{"tofNsigmaCompatibilityCascades", 4, "compatibility check for cascades"}; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -129,97 +102,6 @@ struct strangepidqa { // Event counter histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, 100.0f}}); - // Presence of negative and positive signals and event time - auto hPositiveStatus = histos.add("hPositiveStatus", "hPositiveStatus", kTH1F, {{4, -0.5f, 3.5f}}); - auto hNegativeStatus = histos.add("hNegativeStatus", "hNegativeStatus", kTH1F, {{4, -0.5f, 3.5f}}); - auto hPositiveStatusReachedTOF = histos.add("hPositiveStatusReachedTOF", "hPositiveStatusReachedTOF", kTH1F, {{4, -0.5f, 3.5f}}); - auto hNegativeStatusReachedTOF = histos.add("hNegativeStatusReachedTOF", "hNegativeStatusReachedTOF", kTH1F, {{4, -0.5f, 3.5f}}); - hPositiveStatus->GetXaxis()->SetBinLabel(1, "All positive"); - hPositiveStatus->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); - hPositiveStatus->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); - hPositiveStatus->GetXaxis()->SetBinLabel(4, "Has full time info"); - hNegativeStatus->GetXaxis()->SetBinLabel(1, "All negative"); - hNegativeStatus->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); - hNegativeStatus->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); - hNegativeStatus->GetXaxis()->SetBinLabel(4, "Has full time info"); - - hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(1, "All positive"); - hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); - hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); - hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(4, "Has full time info"); - hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(1, "All negative"); - hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); - hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); - hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(4, "Has full time info"); - - // V0 Radius - histos.add("hLambdaMass", "hLambdaMass", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hAssocLambdaMass", "hAssocLambdaMass", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hAssocLambdaMassGoodTime", "hAssocLambdaMassGoodTime", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hAssocLambdaMassBadTime", "hAssocLambdaMassBadTime", {HistType::kTH1F, {axisLambdaMass}}); - - // V0 Radius - histos.add("h2dLambdaRadiusVsPt", "hLambdaRadiusVsPt", {HistType::kTH2F, {axisPt, axisRadius}}); - - // Invariant Mass - histos.add("h2dLambdaMassVsPt", "hLambdaMassVsPt", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - - // Invariant Mass - histos.add("h2dLambdaMassVsTOFCut", "h2dLambdaMassVsTOFCut", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); - histos.add("h2dLambdaMassVsTOFCutWithSignals", "h2dLambdaMassVsTOFCutWithSignals", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); - histos.add("h2dLambdaMassVsTOFCutMeson", "h2dLambdaMassVsTOFCutMeson", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); - histos.add("h2dLambdaMassVsTOFCutMesonWithSignals", "h2dLambdaMassVsTOFCutMesonWithSignals", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); - - // Invariant Mass with TOF selections - histos.add("hLambdaMass_ProtonTOF", "hLambdaMass_ProtonTOF", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hLambdaMass_PionTOF", "hLambdaMass_PionTOF", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hLambdaMass_AllTOF", "hLambdaMass_AllTOF", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hLambdaMass_DeltaDecayTime", "hLambdaMass_DeltaDecayTime", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_ProtonTOF", "hLambdaMassVsPtProtonTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_PionTOF", "hLambdaMassVsPtPionTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_AllTOF", "hLambdaMassVsPtAllTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_DeltaDecayTime", "hLambdaMassVsPtDeltaDecayTime", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - - // Invariant Mass with TOF selections - histos.add("hLambdaMass_InvertProtonTOF", "hLambdaMass_InvertProtonTOF", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hLambdaMass_InvertPionTOF", "hLambdaMass_InvertPionTOF", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("hLambdaMass_InvertAllTOF", "hLambdaMass_InvertAllTOF", {HistType::kTH1F, {axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_InvertProtonTOF", "hLambdaMassVsPtInvertProtonTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_InvertPionTOF", "hLambdaMassVsPtInvertPionTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("h2dLambdaMassVsPt_InvertAllTOF", "hLambdaMassVsPtInvertAllTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - - // radius vs prong length - histos.add("h2dProtonLengthVsRadius", "h2dProtonLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); - histos.add("h2dPionLengthVsRadius", "h2dPionLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); - - // recalculated vs topv lengths - histos.add("h2dProtonLengthVsLengthToPV", "h2dProtonLengthVsRadiusToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); - histos.add("h2dPionLengthVsLengthToPV", "h2dPionLengthVsLengthToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); - - // TOF PID testing for prongs - histos.add("h2dProtonDeltaTimeVsPt", "h2dProtonDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dProtonDeltaTimeVsRadius", "h2dProtonDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); - histos.add("h2dPionDeltaTimeVsPt", "h2dPionDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dPionDeltaTimeVsRadius", "h2dPionDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); - - // TOF PID testing for prongs - histos.add("h2dProtonDeltaTimeVsPt_MassSelected", "h2dProtonDeltaTimeVsPt_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dProtonDeltaTimeVsRadius_MassSelected", "h2dProtonDeltaTimeVsRadius_MassSelected", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); - histos.add("h2dPionDeltaTimeVsPt_MassSelected", "h2dPionDeltaTimeVsPt_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dPionDeltaTimeVsRadius_MassSelected", "h2dPionDeltaTimeVsRadius_MassSelected", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); - - // delta lambda decay time - histos.add("h2dLambdaDeltaDecayTime", "h2dLambdaDeltaDecayTime", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dLambdaDeltaDecayTime_MassSelected", "h2dLambdaDeltaDecayTime_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - - // beta plots - histos.add("h2dLambdaBeta", "h2dLambdaBeta", {HistType::kTH2F, {axisPt, axisBeta}}); - histos.add("h2dLambdaBeta_MassSelected", "h2dLambdaBeta_MassSelected", {HistType::kTH2F, {axisPt, axisBeta}}); - - // length vs time for prongs / debug - histos.add("h2dTimeVsLengthProtonProng", "h2dTimeVsLengthProtonProng", {HistType::kTH2F, {axisLength, axisTime}}); - histos.add("h2dTimeVsLengthPionProng", "h2dTimeVsLengthPionProng", {HistType::kTH2F, {axisLength, axisTime}}); - histos.add("h1dMassK0Short", "h1dMassK0Short", {HistType::kTH1F, {axisK0ShortMass}}); histos.add("h1dMassLambda", "h1dMassLambda", {HistType::kTH1F, {axisLambdaMass}}); histos.add("h1dMassAntiLambda", "h1dMassAntiLambda", {HistType::kTH1F, {axisLambdaMass}}); @@ -230,39 +112,21 @@ struct strangepidqa { histos.add("h3dMassK0Short", "h3dMassK0Short", {HistType::kTH3F, {centAxis, axisPt, axisK0ShortMass}}); histos.add("h3dMassLambda", "h3dMassLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); - histos.add("h3dMassCompatibleK0Short", "h3dMassCompatibleK0Short", {HistType::kTH3F, {centAxis, axisPt, axisK0ShortMass}}); histos.add("h3dMassCompatibleLambda", "h3dMassCompatibleLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); histos.add("h3dMassCompatibleAntiLambda", "h3dMassCompatibleAntiLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); - // --- ASSOCIATED --- - // V0 Radius - if (doprocessSim) { - histos.add("h2dAssocLambdaRadiusVsPt", "hLambdaRadiusVsPt", {HistType::kTH2F, {axisPt, axisRadius}}); + // cross-check if compatibility requested with primary TOF instead (requires non-derived) + histos.add("h3dPrimaryTOFMassCompatibleK0Short", "h3dPrimaryTOFMassCompatibleK0Short", {HistType::kTH3F, {centAxis, axisPt, axisK0ShortMass}}); + histos.add("h3dPrimaryTOFMassCompatibleLambda", "h3dPrimaryTOFMassCompatibleLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); + histos.add("h3dPrimaryTOFMassCompatibleAntiLambda", "h3dPrimaryTOFMassCompatibleAntiLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); - // Invariant Mass - histos.add("h2dAssocLambdaMassVsPt", "hLambdaMassVsPt", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - - // radius vs prong length - histos.add("h2dAssocProtonLengthVsRadius", "h2dAssocProtonLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); - histos.add("h2dAssocPionLengthVsRadius", "h2dAssocPionLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); - - // recalculated vs topv lengths - histos.add("h2dAssocProtonLengthVsLengthToPV", "h2dAssocProtonLengthVsRadiusToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); - histos.add("h2dAssocPionLengthVsLengthToPV", "h2dAssocPionLengthVsLengthToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); - - // TOF PID testing for prongs - histos.add("h2dAssocProtonDeltaTimeVsPt", "h2dAssocProtonDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dAssocProtonDeltaTimeVsRadius", "h2dAssocProtonDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); - histos.add("h2dAssocPionDeltaTimeVsPt", "h2dAssocPionDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dAssocPionDeltaTimeVsRadius", "h2dAssocPionDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); - - // delta lambda decay time - histos.add("h2dAssocLambdaDeltaDecayTime", "h2dAssocLambdaDeltaDecayTime", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - histos.add("h2dAssocLambdaDeltaDecayTime_MassSelected", "h2dAssocLambdaDeltaDecayTime_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - } + // plot Nsigma: primary vs secondary TOF vs pT (use narrow window around mass) + histos.add("h3dNSigmasLaPr", "h3dNSigmasLaPr", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + histos.add("h3dNSigmasLaPi", "h3dNSigmasLaPi", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + histos.add("h3dNSigmasK0Pi", "h3dNSigmasK0Pi", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); - if (doprocessCascades) { + if (doprocessCascades || doprocessCascadesNonDerived) { histos.add("h1dMassXiMinus", "h1dMassXiMinus", {HistType::kTH1F, {massAxisXi}}); histos.add("h1dMassXiPlus", "h1dMassXiPlus", {HistType::kTH1F, {massAxisXi}}); histos.add("h1dMassOmegaMinus", "h1dMassOmegaMinus", {HistType::kTH1F, {massAxisOmega}}); @@ -276,19 +140,30 @@ struct strangepidqa { histos.add("h3dMassXiPlus", "h3dMassXiPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); histos.add("h3dMassOmegaMinus", "h3dMassOmegaMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); histos.add("h3dMassOmegaPlus", "h3dMassOmegaPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); - histos.add("h3dMassCompatibleXiMinus", "h3dMassCompatibleXiMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); histos.add("h3dMassCompatibleXiPlus", "h3dMassCompatibleXiPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); histos.add("h3dMassCompatibleOmegaMinus", "h3dMassCompatibleOmegaMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); histos.add("h3dMassCompatibleOmegaPlus", "h3dMassCompatibleOmegaPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); + + // cross-check if compatibility requested with primary TOF instead (requires non-derived) + histos.add("h3dPrimaryTOFMassCompatibleXiMinus", "h3dPrimaryTOFMassCompatibleXiMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); + histos.add("h3dPrimaryTOFMassCompatibleXiPlus", "h3dPrimaryTOFMassCompatibleXiPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); + histos.add("h3dPrimaryTOFMassCompatibleOmegaMinus", "h3dPrimaryTOFMassCompatibleOmegaMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); + histos.add("h3dPrimaryTOFMassCompatibleOmegaPlus", "h3dPrimaryTOFMassCompatibleOmegaPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); + + // plot Nsigma: primary vs secondary TOF vs pT (use narrow window around mass) + histos.add("h3dNSigmasXiLaPr", "h3dNSigmasXiLaPr", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + histos.add("h3dNSigmasXiLaPi", "h3dNSigmasXiLaPi", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + histos.add("h3dNSigmasXiPi", "h3dNSigmasXiPi", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + + histos.add("h3dNSigmasOmLaPr", "h3dNSigmasOmLaPr", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + histos.add("h3dNSigmasOmLaPi", "h3dNSigmasOmLaPi", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); + histos.add("h3dNSigmasOmKa", "h3dNSigmasOmKa", {HistType::kTH3F, {axisNSigma, axisNSigma, axisPt}}); } } void processReal(soa::Join::iterator const& coll, soa::Join const& v0s, soa::Join const&) { - if (coll.centFT0C() > maxCentrality || coll.centFT0C() < minCentrality) - return; - for (auto& lambda : v0s) { // selecting photons from Sigma0 if (TMath::Abs(lambda.eta()) > 0.5) @@ -326,127 +201,157 @@ struct strangepidqa { histos.fill(HIST("h1dMassCompatibleK0Short"), lambda.mK0Short()); } } + } + } - histos.fill(HIST("h2dLambdaMassVsTOFCut"), lambda.mLambda(), TMath::Abs(lambda.posTOFDeltaTLaPr())); - histos.fill(HIST("h2dLambdaMassVsTOFCutMeson"), lambda.mLambda(), TMath::Abs(lambda.negTOFDeltaTLaPi())); - - if (lambda.v0radius() < minV0Radius) - continue; - - histos.fill(HIST("h2dLambdaDeltaDecayTime"), lambda.pt(), lambda.deltaDecayTimeLambda()); - if (TMath::Abs(lambda.mLambda() - 1.115683) < 0.01 && lambda.v0cosPA() > minCosPA) { - histos.fill(HIST("h2dLambdaDeltaDecayTime_MassSelected"), lambda.pt(), lambda.deltaDecayTimeLambda()); - } + // ____________________________________________________________________________ + // QA TOF NSigma quantities + Filter preFilter = + nabs(aod::cascdata::dcapostopv) > v0setting_dcapostopv&& nabs(aod::cascdata::dcanegtopv) > v0setting_dcanegtopv&& nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv&& aod::cascdata::dcaV0daughters < v0setting_dcav0dau&& aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau; - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass"), lambda.mLambda()); + void processCascades(soa::Join const& collisions, soa::Filtered> const& Cascades, soa::Join const&) + { + for (auto& casc : Cascades) { + auto col = collisions.rawIteratorAt(casc.straCollisionId()); - histos.fill(HIST("h2dLambdaRadiusVsPt"), lambda.pt(), lambda.v0radius()); - histos.fill(HIST("h2dLambdaMassVsPt"), lambda.pt(), lambda.mLambda()); + // major selections here + if (casc.v0radius() > v0setting_radius && + casc.cascradius() > cascadesetting_cascradius && + casc.v0cosPA(col.posX(), col.posY(), col.posZ()) > v0setting_cospa && + casc.casccosPA(col.posX(), col.posY(), col.posZ()) > cascadesetting_cospa && + casc.dcav0topv(col.posX(), col.posY(), col.posZ()) > cascadesetting_mindcav0topv && + TMath::Abs(casc.mLambda() - 1.115683) < cascadesetting_v0masswindow) { - histos.fill(HIST("h2dProtonDeltaTimeVsPt"), lambda.pt(), lambda.posTOFDeltaTLaPr()); - histos.fill(HIST("h2dProtonDeltaTimeVsRadius"), lambda.v0radius(), lambda.posTOFDeltaTLaPr()); - histos.fill(HIST("h2dPionDeltaTimeVsPt"), lambda.pt(), lambda.negTOFDeltaTLaPi()); - histos.fill(HIST("h2dPionDeltaTimeVsRadius"), lambda.v0radius(), lambda.negTOFDeltaTLaPi()); - histos.fill(HIST("h2dLambdaBeta"), lambda.p(), lambda.tofBetaLambda()); + auto negExtra = casc.negTrackExtra_as>(); + auto posExtra = casc.posTrackExtra_as>(); + auto bachExtra = casc.bachTrackExtra_as>(); - if (TMath::Abs(lambda.mLambda() - 1.115683) < 0.01 && lambda.v0cosPA() > minCosPA) { - histos.fill(HIST("h2dProtonDeltaTimeVsPt_MassSelected"), lambda.pt(), lambda.posTOFDeltaTLaPr()); - histos.fill(HIST("h2dProtonDeltaTimeVsRadius_MassSelected"), lambda.v0radius(), lambda.posTOFDeltaTLaPr()); - histos.fill(HIST("h2dPionDeltaTimeVsPt_MassSelected"), lambda.pt(), lambda.negTOFDeltaTLaPi()); - histos.fill(HIST("h2dPionDeltaTimeVsRadius_MassSelected"), lambda.v0radius(), lambda.negTOFDeltaTLaPi()); - histos.fill(HIST("h2dLambdaBeta_MassSelected"), lambda.p(), lambda.tofBetaLambda()); - } + if (negExtra.tpcCrossedRows() < tpcCrossedRows || posExtra.tpcCrossedRows() < tpcCrossedRows || bachExtra.tpcCrossedRows() < tpcCrossedRows) + continue; - // Standard selection of time - if (TMath::Abs(lambda.deltaDecayTimeLambda()) < maxDeltaTimeDecay) { - histos.fill(HIST("h2dLambdaMassVsPt_DeltaDecayTime"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_DeltaDecayTime"), lambda.mLambda()); - } + if (casc.sign() < 0) { + if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(bachExtra.tpcNSigmaPi()) < tpcNsigmaBachelor) { + histos.fill(HIST("h3dMassXiMinus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassXiMinus"), casc.mXi()); + if (casc.tofXiCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleXiMinus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassCompatibleXiMinus"), casc.mXi()); + } + } + if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(bachExtra.tpcNSigmaKa()) < tpcNsigmaBachelor) { + histos.fill(HIST("h3dMassOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassOmegaMinus"), casc.mOmega()); + if (casc.tofOmegaCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassCompatibleOmegaMinus"), casc.mOmega()); + } + } + } else { + if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(bachExtra.tpcNSigmaPi()) < tpcNsigmaBachelor) { + histos.fill(HIST("h3dMassXiPlus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassXiPlus"), casc.mXi()); + if (casc.tofXiCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleXiPlus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassCompatibleXiPlus"), casc.mXi()); + } + } - if (TMath::Abs(lambda.posTOFDeltaTLaPr()) < maxDeltaTimeProton) { - histos.fill(HIST("h2dLambdaMassVsPt_ProtonTOF"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_ProtonTOF"), lambda.mLambda()); - } - if (TMath::Abs(lambda.negTOFDeltaTLaPi()) < maxDeltaTimeProton) { - histos.fill(HIST("h2dLambdaMassVsPt_PionTOF"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_PionTOF"), lambda.mLambda()); - if (TMath::Abs(lambda.posTOFDeltaTLaPr()) < maxDeltaTimeProton) { - histos.fill(HIST("h2dLambdaMassVsPt_AllTOF"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_AllTOF"), lambda.mLambda()); - } - } - // Inversion of time selection for debug - // if(TMath::Abs(lambda.deltaDecayTimeLambda())>maxDeltaTimeDecay && TMath::Abs(lambda.deltaDecayTimeLambda()) < 5e+4){ - // histos.fill(HIST("h2dLambdaMassVsPt_DeltaDecayTime"), lambda.pt(), lambda.mLambda()); - // if(lambda.pt()>minPtV0 && lambda.pt() < maxPtV0) histos.fill(HIST("hLambdaMass_DeltaDecayTime"), lambda.mLambda()); - // } - - if (TMath::Abs(lambda.posTOFDeltaTLaPr()) > maxDeltaTimeProton && TMath::Abs(lambda.posTOFDeltaTLaPr()) < 5e+4) { - histos.fill(HIST("h2dLambdaMassVsPt_InvertProtonTOF"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_InvertProtonTOF"), lambda.mLambda()); - } - if (TMath::Abs(lambda.negTOFDeltaTLaPi()) > maxDeltaTimeProton && TMath::Abs(lambda.negTOFDeltaTLaPi()) < 5e+4) { - histos.fill(HIST("h2dLambdaMassVsPt_InvertPionTOF"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_InvertPionTOF"), lambda.mLambda()); - if (TMath::Abs(lambda.posTOFDeltaTLaPr()) > maxDeltaTimeProton && TMath::Abs(lambda.posTOFDeltaTLaPr()) < 5e+4) { - histos.fill(HIST("h2dLambdaMassVsPt_InvertAllTOF"), lambda.pt(), lambda.mLambda()); - if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) - histos.fill(HIST("hLambdaMass_InvertAllTOF"), lambda.mLambda()); + if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(bachExtra.tpcNSigmaKa()) < tpcNsigmaBachelor) { + histos.fill(HIST("h3dMassOmegaPlus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassOmegaPlus"), casc.mOmega()); + if (casc.tofOmegaCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleOmegaPlus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassCompatibleOmegaPlus"), casc.mOmega()); + } + } } } } } - void processSim(aod::StraCollision const&, soa::Join const& v0s) + void processRealNonDerived(soa::Join const& collisions, soa::Join const& v0s, soa::Join const&) { - for (auto& lambda : v0s) { // selecting photons from Sigma0 - if (lambda.pdgCode() != 3122) - continue; - if (!lambda.isPhysicalPrimary()) - continue; - if (lambda.pdgCodePositive() != 2212) - continue; - if (lambda.pdgCodeNegative() != -211) + for (auto const& col : collisions) { + histos.fill(HIST("hEventCentrality"), col.centFT0C()); + } + + for (auto& lambda : v0s) { + auto coll = collisions.rawIteratorAt(lambda.collisionId()); + + if (TMath::Abs(lambda.eta()) > 0.5) continue; - histos.fill(HIST("hAssocLambdaMass"), lambda.mLambda()); + auto negExtra = lambda.negTrack_as>(); + auto posExtra = lambda.posTrack_as>(); - histos.fill(HIST("h2dAssocLambdaRadiusVsPt"), lambda.pt(), lambda.v0radius()); - histos.fill(HIST("h2dAssocLambdaMassVsPt"), lambda.pt(), lambda.mLambda()); + bool primaryTOFcompatible_Lambda = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPr() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)); - histos.fill(HIST("h2dAssocProtonDeltaTimeVsPt"), lambda.pt(), lambda.posTOFDeltaTLaPr()); - histos.fill(HIST("h2dAssocProtonDeltaTimeVsRadius"), lambda.v0radius(), lambda.posTOFDeltaTLaPr()); - histos.fill(HIST("h2dAssocPionDeltaTimeVsPt"), lambda.pt(), lambda.negTOFDeltaTLaPi()); - histos.fill(HIST("h2dAssocPionDeltaTimeVsRadius"), lambda.v0radius(), lambda.negTOFDeltaTLaPi()); + bool primaryTOFcompatible_AntiLambda = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPr() < tofNsigmaCompatibilityCascades.value)); - // delta lambda decay time - histos.fill(HIST("h2dAssocLambdaDeltaDecayTime"), lambda.pt(), lambda.deltaDecayTimeLambda()); - } - } + bool primaryTOFcompatible_K0Short = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)); - // ____________________________________________________________________________ - // QA TOF NSigma quantities + if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion) { + // lambda case + histos.fill(HIST("h3dMassLambda"), coll.centFT0C(), lambda.pt(), lambda.mLambda()); + histos.fill(HIST("h1dMassLambda"), lambda.mLambda()); + if (lambda.tofLambdaCompatibility(tofNsigmaCompatibility.value)) { + histos.fill(HIST("h3dMassCompatibleLambda"), coll.centFT0C(), lambda.pt(), lambda.mLambda()); + histos.fill(HIST("h1dMassCompatibleLambda"), lambda.mLambda()); + } + if (primaryTOFcompatible_Lambda) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleLambda"), coll.centFT0C(), lambda.pt(), lambda.mLambda()); + } + if (std::abs(lambda.mLambda() - o2::constants::physics::MassLambda) < massWindowForNSigmaPlots.value) { + histos.fill(HIST("h3dNSigmasLaPr"), lambda.tofNSigmaLaPr(), posExtra.tofNSigmaPr(), lambda.pt()); + histos.fill(HIST("h3dNSigmasLaPi"), lambda.tofNSigmaLaPi(), negExtra.tofNSigmaPi(), lambda.pt()); + } + } - Partition> negCasc = aod::cascdata::sign < 0; - Partition> posCasc = aod::cascdata::sign > 0; + if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaPion) { + // lambda case + histos.fill(HIST("h3dMassAntiLambda"), coll.centFT0C(), lambda.pt(), lambda.mAntiLambda()); + histos.fill(HIST("h1dMassAntiLambda"), lambda.mAntiLambda()); + if (lambda.tofAntiLambdaCompatibility(tofNsigmaCompatibility.value)) { + histos.fill(HIST("h3dMassCompatibleAntiLambda"), coll.centFT0C(), lambda.pt(), lambda.mAntiLambda()); + histos.fill(HIST("h1dMassCompatibleAntiLambda"), lambda.mAntiLambda()); + } + if (primaryTOFcompatible_AntiLambda) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleAntiLambda"), coll.centFT0C(), lambda.pt(), lambda.mAntiLambda()); + } + } - Filter preFilter = - nabs(aod::cascdata::dcapostopv) > v0setting_dcapostopv&& nabs(aod::cascdata::dcanegtopv) > v0setting_dcanegtopv&& nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv&& aod::cascdata::dcaV0daughters < v0setting_dcav0dau&& aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau; + if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaPion) { + // lambda case + histos.fill(HIST("h3dMassK0Short"), coll.centFT0C(), lambda.pt(), lambda.mK0Short()); + histos.fill(HIST("h1dMassK0Short"), lambda.mK0Short()); + if (lambda.tofK0ShortCompatibility(tofNsigmaCompatibility.value)) { + histos.fill(HIST("h3dMassCompatibleK0Short"), coll.centFT0C(), lambda.pt(), lambda.mK0Short()); + histos.fill(HIST("h1dMassCompatibleK0Short"), lambda.mK0Short()); + } + if (primaryTOFcompatible_K0Short) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleK0Short"), coll.centFT0C(), lambda.pt(), lambda.mK0Short()); + } + if (std::abs(lambda.mK0Short() - o2::constants::physics::MassK0Short) < massWindowForNSigmaPlots.value) { + histos.fill(HIST("h3dNSigmasK0Pi"), lambda.tofNSigmaLaPi(), posExtra.tofNSigmaPi(), lambda.pt()); + histos.fill(HIST("h3dNSigmasK0Pi"), lambda.tofNSigmaLaPi(), negExtra.tofNSigmaPi(), lambda.pt()); + } + } + } + } - void processCascades(soa::Join::iterator const& col, soa::Filtered> const& Cascades, soa::Join const&) + // to test original data (not derived) as well, compare with primary TOF Nsigmas + // don't do grouping, faster to simply stream through + void processCascadesNonDerived(soa::Join const& collisions, soa::Filtered> const& Cascades, soa::Join const&) { - histos.fill(HIST("hEventCentrality"), col.centFT0C()); - if (col.centFT0C() > maxCentrality || col.centFT0C() < minCentrality) - return; - for (auto& casc : Cascades) { + auto col = collisions.rawIteratorAt(casc.collisionId()); + // major selections here if (casc.v0radius() > v0setting_radius && casc.cascradius() > cascadesetting_cascradius && @@ -455,12 +360,33 @@ struct strangepidqa { casc.dcav0topv(col.posX(), col.posY(), col.posZ()) > cascadesetting_mindcav0topv && TMath::Abs(casc.mLambda() - 1.115683) < cascadesetting_v0masswindow) { - auto negExtra = casc.negTrackExtra_as>(); - auto posExtra = casc.posTrackExtra_as>(); - auto bachExtra = casc.bachTrackExtra_as>(); + auto negExtra = casc.negTrack_as>(); + auto posExtra = casc.posTrack_as>(); + auto bachExtra = casc.bachelor_as>(); - if (negExtra.tpcCrossedRows() < tpcCrossedRows || posExtra.tpcCrossedRows() < tpcCrossedRows || bachExtra.tpcCrossedRows() < tpcCrossedRows) + if (negExtra.tpcNClsCrossedRows() < tpcCrossedRows || posExtra.tpcNClsCrossedRows() < tpcCrossedRows || bachExtra.tpcNClsCrossedRows() < tpcCrossedRows) { continue; + } + + bool primaryTOFcompatible_XiMinus = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPr() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)) && + (!bachExtra.hasTOF() || (bachExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)); + + bool primaryTOFcompatible_XiPlus = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPr() < tofNsigmaCompatibilityCascades.value)) && + (!bachExtra.hasTOF() || (bachExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)); + + bool primaryTOFcompatible_OmegaMinus = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPr() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)) && + (!bachExtra.hasTOF() || (bachExtra.tofNSigmaKa() < tofNsigmaCompatibilityCascades.value)); + + bool primaryTOFcompatible_OmegaPlus = + (!posExtra.hasTOF() || (posExtra.tofNSigmaPi() < tofNsigmaCompatibilityCascades.value)) && + (!negExtra.hasTOF() || (negExtra.tofNSigmaPr() < tofNsigmaCompatibilityCascades.value)) && + (!bachExtra.hasTOF() || (bachExtra.tofNSigmaKa() < tofNsigmaCompatibilityCascades.value)); if (casc.sign() < 0) { if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(bachExtra.tpcNSigmaPi()) < tpcNsigmaBachelor) { @@ -470,6 +396,14 @@ struct strangepidqa { histos.fill(HIST("h3dMassCompatibleXiMinus"), col.centFT0C(), casc.pt(), casc.mXi()); histos.fill(HIST("h1dMassCompatibleXiMinus"), casc.mXi()); } + if (primaryTOFcompatible_XiMinus) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleXiMinus"), col.centFT0C(), casc.pt(), casc.mXi()); + } + if (std::abs(casc.mXi() - o2::constants::physics::MassXiMinus) < massWindowForNSigmaPlots.value) { + histos.fill(HIST("h3dNSigmasXiLaPr"), casc.tofNSigmaXiLaPr(), posExtra.tofNSigmaPr(), casc.pt()); + histos.fill(HIST("h3dNSigmasXiLaPi"), casc.tofNSigmaXiLaPi(), negExtra.tofNSigmaPi(), casc.pt()); + histos.fill(HIST("h3dNSigmasXiPi"), casc.tofNSigmaXiPi(), bachExtra.tofNSigmaPi(), casc.pt()); + } } if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(bachExtra.tpcNSigmaKa()) < tpcNsigmaBachelor) { histos.fill(HIST("h3dMassOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); @@ -478,6 +412,14 @@ struct strangepidqa { histos.fill(HIST("h3dMassCompatibleOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); histos.fill(HIST("h1dMassCompatibleOmegaMinus"), casc.mOmega()); } + if (primaryTOFcompatible_OmegaMinus) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); + } + if (std::abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < massWindowForNSigmaPlots.value) { + histos.fill(HIST("h3dNSigmasOmLaPr"), casc.tofNSigmaOmLaPr(), posExtra.tofNSigmaPr(), casc.pt()); + histos.fill(HIST("h3dNSigmasOmLaPi"), casc.tofNSigmaOmLaPi(), negExtra.tofNSigmaPi(), casc.pt()); + histos.fill(HIST("h3dNSigmasOmKa"), casc.tofNSigmaOmKa(), bachExtra.tofNSigmaKa(), casc.pt()); + } } } else { if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(bachExtra.tpcNSigmaPi()) < tpcNsigmaBachelor) { @@ -487,6 +429,9 @@ struct strangepidqa { histos.fill(HIST("h3dMassCompatibleXiPlus"), col.centFT0C(), casc.pt(), casc.mXi()); histos.fill(HIST("h1dMassCompatibleXiPlus"), casc.mXi()); } + if (primaryTOFcompatible_XiPlus) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleXiPlus"), col.centFT0C(), casc.pt(), casc.mXi()); + } } if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(bachExtra.tpcNSigmaKa()) < tpcNsigmaBachelor) { @@ -496,6 +441,9 @@ struct strangepidqa { histos.fill(HIST("h3dMassCompatibleOmegaPlus"), col.centFT0C(), casc.pt(), casc.mOmega()); histos.fill(HIST("h1dMassCompatibleOmegaPlus"), casc.mOmega()); } + if (primaryTOFcompatible_OmegaPlus) { + histos.fill(HIST("h3dPrimaryTOFMassCompatibleOmegaPlus"), col.centFT0C(), casc.pt(), casc.mOmega()); + } } } } @@ -503,8 +451,11 @@ struct strangepidqa { } PROCESS_SWITCH(strangepidqa, processReal, "Produce real information", true); - PROCESS_SWITCH(strangepidqa, processSim, "Produce simulated information", true); PROCESS_SWITCH(strangepidqa, processCascades, "Process real cascades", true); + + // non-derived options + PROCESS_SWITCH(strangepidqa, processRealNonDerived, "Process real cascades from non-derived data", true); + PROCESS_SWITCH(strangepidqa, processCascadesNonDerived, "Process real cascades from non-derived data", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Resonances/f1protoncorrelation.cxx b/PWGLF/Tasks/Resonances/f1protoncorrelation.cxx index af45b89b8da..41a21b66358 100644 --- a/PWGLF/Tasks/Resonances/f1protoncorrelation.cxx +++ b/PWGLF/Tasks/Resonances/f1protoncorrelation.cxx @@ -13,31 +13,51 @@ /// \author sourav kundu /// \since 02/11/2023 +#include "PWGLF/DataModel/ReducedF1ProtonTables.h" + +#include "Common/Core/trackUtilities.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include -#include + #include #include +#include #include + #include + #include #include #include -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/StepTHn.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/ReducedF1ProtonTables.h" -#include "CommonConstants/PhysicsConstants.h" - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; struct f1protoncorrelation { + + double bz = 0.; + double bz2 = 0.; + + // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + struct : ConfigurableGroup { + Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + } cfgCcdbParam; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // PID selection Configurable nsigmaCutTPC{"nsigmacutTPC", 3.0, "Value of the TPC Nsigma cut"}; @@ -70,6 +90,7 @@ struct f1protoncorrelation { ConfigurableAxis configThnAxisKstar{"configThnAxisKstar", {100, 0.0, 1.0}, "#it{k}^{*} (GeV/#it{c})"}; ConfigurableAxis configThnAxisPtProton{"configThnAxisPtProton", {20, 0.0, 4.}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis configThnAxisNsigma{"configThnAxisNsigma", {90, -9.0, 9.0}, "NsigmaCombined"}; + ConfigurableAxis configThnAxisCharge{"configThnAxisCharge", {5, -2.5, 2.5}, "Charge"}; // mix event bining policy ColumnBinningPolicy colBinningFemto{{CfgVtxBins, CfgMultBins}, true}; @@ -83,31 +104,89 @@ struct f1protoncorrelation { const AxisSpec thnAxisPtProton{configThnAxisPtProton, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec thnAxisKstar{configThnAxisKstar, "#it{k}^{*} (GeV/#it{c})"}; const AxisSpec thnAxisNsigma{configThnAxisNsigma, "NsigmaCombined"}; + const AxisSpec thnAxisCharge{configThnAxisCharge, "Charge"}; // register histograms + histos.add("hPhaseSpaceProtonKaonSame", "hPhaseSpaceProtonKaonSame", kTH2F, {{200, -2.0f, 2.0f}, {360, -4.0 * TMath::Pi(), 4.0 * TMath::Pi()}}); + histos.add("hPhaseSpaceProtonPionSame", "hPhaseSpaceProtonPionSame", kTH2F, {{200, -2.0f, 2.0f}, {360, -4.0 * TMath::Pi(), 4.0 * TMath::Pi()}}); + histos.add("hPhaseSpaceProtonKaonMix", "hPhaseSpaceProtonKaonMix", kTH2F, {{200, -2.0f, 2.0f}, {360, -4.0 * TMath::Pi(), 4.0 * TMath::Pi()}}); + histos.add("hPhaseSpaceProtonPionMix", "hPhaseSpaceProtonPionMix", kTH2F, {{200, -2.0f, 2.0f}, {360, -4.0 * TMath::Pi(), 4.0 * TMath::Pi()}}); histos.add("hNsigmaProtonTPC", "Nsigma Proton TPC distribution", kTH2F, {{100, -5.0f, 5.0f}, {100, 0.0f, 10.0f}}); histos.add("hNsigmaKaonTPC", "Nsigma Kaon TPC distribution", kTH2F, {{100, -5.0f, 5.0f}, {100, 0.0f, 10.0f}}); histos.add("hNsigmaPionTPC", "Nsigma Pion TPC distribution", kTH2F, {{100, -5.0f, 5.0f}, {100, 0.0f, 10.0f}}); histos.add("hNsigmaPionKaonTPC", "Nsigma Pion Kaon TPC correlation", kTH2F, {{100, -5.0f, 5.0f}, {100, -5.0f, 5.0f}}); histos.add("h2SameEventPtCorrelation", "Pt correlation of F1 and proton", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {100, 0.0, 10.0}}); - histos.add("h2SameEventInvariantMassUnlike_mass", "Unlike Sign Invariant mass of f1 same event", kTH3F, {thnAxisKstar, thnAxisPt, thnAxisInvMass}); - histos.add("h2SameEventInvariantMassLike_mass", "Like Sign Invariant mass of f1 same event", kTH3F, {thnAxisKstar, thnAxisPt, thnAxisInvMass}); - histos.add("h2SameEventInvariantMassRot_mass", "Rotational Invariant mass of f1 same event", kTH3F, {thnAxisKstar, thnAxisPt, thnAxisInvMass}); + histos.add("h2SameEventInvariantMassUnlike_mass", "Unlike Sign Invariant mass of f1 same event", kTHnSparseF, {thnAxisKstar, thnAxisPt, thnAxisInvMass, thnAxisCharge}); + histos.add("h2SameEventInvariantMassLike_mass", "Like Sign Invariant mass of f1 same event", kTHnSparseF, {thnAxisKstar, thnAxisPt, thnAxisInvMass, thnAxisCharge}); + histos.add("h2SameEventInvariantMassRot_mass", "Rotational Invariant mass of f1 same event", kTHnSparseF, {thnAxisKstar, thnAxisPt, thnAxisInvMass, thnAxisCharge}); - histos.add("h2MixEventInvariantMassUnlike_mass", "Unlike Sign Invariant mass of f1 mix event", kTH3F, {thnAxisKstar, thnAxisPt, thnAxisInvMass}); - histos.add("h2MixEventInvariantMassLike_mass", "Like Sign Invariant mass of f1 mix event", kTH3F, {thnAxisKstar, thnAxisPt, thnAxisInvMass}); - histos.add("h2MixEventInvariantMassRot_mass", "Rotational Sign Invariant mass of f1 mix event", kTH3F, {thnAxisKstar, thnAxisPt, thnAxisInvMass}); + histos.add("h2MixEventInvariantMassUnlike_mass", "Unlike Sign Invariant mass of f1 mix event", kTHnSparseF, {thnAxisKstar, thnAxisPt, thnAxisInvMass, thnAxisCharge}); + histos.add("h2MixEventInvariantMassLike_mass", "Like Sign Invariant mass of f1 mix event", kTHnSparseF, {thnAxisKstar, thnAxisPt, thnAxisInvMass, thnAxisCharge}); + histos.add("h2MixEventInvariantMassRot_mass", "Rotational Sign Invariant mass of f1 mix event", kTHnSparseF, {thnAxisKstar, thnAxisPt, thnAxisInvMass, thnAxisCharge}); if (fillSparse) { - histos.add("SEMassUnlike", "SEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma}); - histos.add("SEMassLike", "SEMassLike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma}); - histos.add("SEMassRot", "SEMassRot", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma}); + histos.add("SEMassUnlike", "SEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma, thnAxisCharge}); + histos.add("SEMassLike", "SEMassLike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma, thnAxisCharge}); + histos.add("SEMassRot", "SEMassRot", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma, thnAxisCharge}); + + histos.add("MEMassUnlike", "MEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma, thnAxisCharge}); + histos.add("MEMassLike", "MEMassLike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma, thnAxisCharge}); + histos.add("MEMassRot", "MEMassRot", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma, thnAxisCharge}); + } + + ccdb->setURL(cfgCcdbParam.cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } + + int getMagneticField(uint64_t timestamp) + { + // Get the magnetic field + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("/GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %2.2f kG", timestamp, 0.1 * grpo->getNominalL3Field()); + } + return 0.1 * grpo->getNominalL3Field(); + } + + /// Magnetic field to be provided in Tesla + static constexpr float tmpRadiiTPC[9] = {85., 105., 125., 145., 165., 185., 205., 225., 245.}; + float PhiAtSpecificRadiiTPC(const TLorentzVector part1, const TLorentzVector part2, float charge1 = 0, int charge2 = 0, float magfield1 = 0.0, float magfield2 = 0.0) + { + float pt1 = part1.Pt(); + float phi1 = part1.Phi(); + float value1 = 0.0; + float count1 = 0.0; + for (size_t i = 0; i < 9; i++) { + auto arg1 = 0.3 * charge1 * magfield1 * tmpRadiiTPC[i] * 0.01 / (2. * pt1); + if (std::fabs(arg1) < 1) { + value1 = value1 + (phi1 - std::asin(arg1)); + count1 = count1 + 1.0; + } + } + value1 = value1 / count1; - histos.add("MEMassUnlike", "MEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma}); - histos.add("MEMassLike", "MEMassLike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma}); - histos.add("MEMassRot", "MEMassRot", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPtProton, thnAxisKstar, thnAxisNsigma}); + float pt2 = part2.Pt(); + float phi2 = part2.Phi(); + float value2 = 0.0; + float count2 = 0.0; + for (size_t i = 0; i < 9; i++) { + auto arg2 = 0.3 * charge2 * magfield2 * tmpRadiiTPC[i] * 0.01 / (2. * pt2); + if (std::fabs(arg2) < 1) { + value2 = value2 + (phi2 - std::asin(arg2)); + count2 = count2 + 1.0; + } } + value2 = value2 / count2; + return value1 - value2; } // get kstar @@ -136,8 +215,21 @@ struct f1protoncorrelation { TLorentzVector F1, Proton, F1ProtonPair, Pion, Kaon, Kshort; TLorentzVector F1Rot, PionRot, KaonKshortPair, KaonKshortPairRot; // Process the data in same event - void process(aod::RedF1PEvents::iterator const& /*collision*/, aod::F1Tracks const& f1tracks, aod::ProtonTracks const& protontracks) + + int currentRunNumber = -999; + int lastRunNumber = -999; + + void process(aod::RedF1PEvents::iterator const& collision, aod::F1Tracks const& f1tracks, aod::ProtonTracks const& protontracks) { + + // auto bc = collision.template bc_as(); + // currentRunNumber = collision.bc_as().runNumber(); + currentRunNumber = collision.runNumber(); + if (currentRunNumber != lastRunNumber) { + bz = getMagneticField(collision.timestamp()); + } + lastRunNumber = currentRunNumber; + for (auto f1track : f1tracks) { if (f1track.f1MassKaonKshort() > maxKKS0Mass) { continue; @@ -207,16 +299,24 @@ struct f1protoncorrelation { histos.fill(HIST("hNsigmaProtonTPC"), protontrack.protonNsigmaTPC(), Proton.Pt()); } histos.fill(HIST("h2SameEventPtCorrelation"), relative_momentum, F1.Pt(), Proton.Pt()); - if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + if (f1track.f1SignalStat() > 0) { + int f1Charge = f1track.f1SignalStat(); + if (f1Charge == 2) { + f1Charge = -1; + } + int pionCharge = -1.0 * f1Charge; + float pairCharge = f1Charge * protontrack.protonCharge(); + histos.fill(HIST("hPhaseSpaceProtonKaonSame"), Proton.Eta() - Kaon.Eta(), PhiAtSpecificRadiiTPC(Proton, Kaon, protontrack.protonCharge(), f1Charge, bz, bz)); // Phase Space Proton kaon + histos.fill(HIST("hPhaseSpaceProtonPionSame"), Proton.Eta() - Kaon.Eta(), PhiAtSpecificRadiiTPC(Proton, Pion, protontrack.protonCharge(), pionCharge, bz, bz)); // Phase Space Proton Pion + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass"), relative_momentum, F1.Pt(), F1.M(), pairCharge); // F1 sign = 1 unlike, F1 sign = -1 like if (fillSparse) { - histos.fill(HIST("SEMassUnlike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC); + histos.fill(HIST("SEMassUnlike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC, pairCharge); } } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass"), relative_momentum, F1.Pt(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass"), relative_momentum, F1.Pt(), F1.M(), protontrack.protonCharge()); if (fillSparse) { - histos.fill(HIST("SEMassLike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC); + histos.fill(HIST("SEMassLike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC, protontrack.protonCharge()); } } if (fillRotation) { @@ -230,10 +330,10 @@ struct f1protoncorrelation { KaonKshortPairRot.SetXYZM(rotKKPx, rotKKPy, KaonKshortPair.Pz(), KaonKshortPair.M()); F1Rot = Pion + KaonKshortPairRot; auto relative_momentum_rot = getkstar(F1Rot, Proton); - if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassRot_mass"), relative_momentum_rot, F1Rot.Pt(), F1Rot.M()); + if (f1track.f1SignalStat() > 0) { + histos.fill(HIST("h2SameEventInvariantMassRot_mass"), relative_momentum_rot, F1Rot.Pt(), F1Rot.M(), protontrack.protonCharge()); if (fillSparse) { - histos.fill(HIST("SEMassRot"), F1Rot.M(), F1Rot.Pt(), Proton.Pt(), relative_momentum_rot, combinedTPC); + histos.fill(HIST("SEMassRot"), F1Rot.M(), F1Rot.Pt(), Proton.Pt(), relative_momentum_rot, combinedTPC, protontrack.protonCharge()); } } } @@ -317,16 +417,16 @@ struct f1protoncorrelation { continue; } auto relative_momentum = getkstar(F1, Proton); - if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + if (t1.f1SignalStat() > 0) { + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass"), relative_momentum, F1.Pt(), F1.M(), 1.0); // F1 sign = 1 unlike, F1 sign = -1 like if (fillSparse) { - histos.fill(HIST("MEMassUnlike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC); + histos.fill(HIST("MEMassUnlike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC, 1.0); } } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass"), relative_momentum, F1.Pt(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass"), relative_momentum, F1.Pt(), F1.M(), 1.0); if (fillSparse) { - histos.fill(HIST("MEMassLike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC); + histos.fill(HIST("MEMassLike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC, 1.0); } } if (fillRotation) { @@ -340,10 +440,10 @@ struct f1protoncorrelation { KaonKshortPairRot.SetXYZM(rotKKPx, rotKKPy, KaonKshortPair.Pz(), KaonKshortPair.M()); F1Rot = Pion + KaonKshortPairRot; auto relative_momentum_rot = getkstar(F1Rot, Proton); - if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassRot_mass"), relative_momentum_rot, F1Rot.Pt(), F1Rot.M()); + if (t1.f1SignalStat() > 0) { + histos.fill(HIST("h2MixEventInvariantMassRot_mass"), relative_momentum_rot, F1Rot.Pt(), F1Rot.M(), 1.0); if (fillSparse) { - histos.fill(HIST("MEMassRot"), F1Rot.M(), F1Rot.Pt(), Proton.Pt(), relative_momentum_rot, combinedTPC); + histos.fill(HIST("MEMassRot"), F1Rot.M(), F1Rot.Pt(), Proton.Pt(), relative_momentum_rot, combinedTPC, 1.0); } } } @@ -360,6 +460,12 @@ struct f1protoncorrelation { if (collision1.index() == collision2.index()) { continue; } + currentRunNumber = collision1.runNumber(); + if (currentRunNumber != lastRunNumber) { + bz = getMagneticField(collision1.timestamp()); + bz2 = getMagneticField(collision2.timestamp()); + } + lastRunNumber = currentRunNumber; auto groupF1 = f1tracks.sliceBy(tracksPerCollisionPresliceF1, collision1.globalIndex()); auto groupProton = protontracks.sliceBy(tracksPerCollisionPresliceP, collision2.globalIndex()); // auto groupF1 = f1tracks.sliceByCached(aod::f1protondaughter::redF1PEventId, collision1.globalIndex(), cache); @@ -419,16 +525,24 @@ struct f1protoncorrelation { continue; } auto relative_momentum = getkstar(F1, Proton); - if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + if (t1.f1SignalStat() > 0) { + int f1Charge = t1.f1SignalStat(); + if (f1Charge == 2) { + f1Charge = -1; + } + int pionCharge = -1.0 * f1Charge; + float pairCharge = f1Charge * t2.protonCharge(); + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass"), relative_momentum, F1.Pt(), F1.M(), pairCharge); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("hPhaseSpaceProtonKaonMix"), Proton.Eta() - Kaon.Eta(), PhiAtSpecificRadiiTPC(Proton, Kaon, t2.protonCharge(), f1Charge, bz, bz2)); // Phase Space Proton kaon + histos.fill(HIST("hPhaseSpaceProtonPionMix"), Proton.Eta() - Kaon.Eta(), PhiAtSpecificRadiiTPC(Proton, Pion, t2.protonCharge(), pionCharge, bz, bz2)); // Phase Space Proton Pion if (fillSparse) { - histos.fill(HIST("MEMassUnlike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC); + histos.fill(HIST("MEMassUnlike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC, pairCharge); } } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass"), relative_momentum, F1.Pt(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass"), relative_momentum, F1.Pt(), F1.M(), t2.protonCharge()); if (fillSparse) { - histos.fill(HIST("MEMassLike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC); + histos.fill(HIST("MEMassLike"), F1.M(), F1.Pt(), Proton.Pt(), relative_momentum, combinedTPC, t2.protonCharge()); } } if (fillRotation) { @@ -442,10 +556,10 @@ struct f1protoncorrelation { KaonKshortPairRot.SetXYZM(rotKKPx, rotKKPy, KaonKshortPair.Pz(), KaonKshortPair.M()); F1Rot = Pion + KaonKshortPairRot; auto relative_momentum_rot = getkstar(F1Rot, Proton); - if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassRot_mass"), relative_momentum_rot, F1Rot.Pt(), F1Rot.M()); + if (t1.f1SignalStat() > 0) { + histos.fill(HIST("h2MixEventInvariantMassRot_mass"), relative_momentum_rot, F1Rot.Pt(), F1Rot.M(), t2.protonCharge()); if (fillSparse) { - histos.fill(HIST("MEMassRot"), F1Rot.M(), F1Rot.Pt(), Proton.Pt(), relative_momentum_rot, combinedTPC); + histos.fill(HIST("MEMassRot"), F1Rot.M(), F1Rot.Pt(), Proton.Pt(), relative_momentum_rot, combinedTPC, t2.protonCharge()); } } } diff --git a/PWGLF/Tasks/Resonances/higherMassResonances.cxx b/PWGLF/Tasks/Resonances/higherMassResonances.cxx index 7b13c8e0596..fbb552a9b29 100644 --- a/PWGLF/Tasks/Resonances/higherMassResonances.cxx +++ b/PWGLF/Tasks/Resonances/higherMassResonances.cxx @@ -237,8 +237,8 @@ struct HigherMassResonances { if (config.qAevents) { rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); rEventSelection.add("hmultiplicity", "multiplicity percentile distribution", {HistType::kTH1F, {{150, 0.0f, 150.0f}}}); - hglue.add("htrackscheck_v0", "htrackscheck_v0", kTH1I, {{15, 0, 15}}); - hglue.add("htrackscheck_v0_daughters", "htrackscheck_v0_daughters", kTH1I, {{15, 0, 15}}); + rEventSelection.add("htrackscheck_v0", "htrackscheck_v0", kTH1I, {{15, 0, 15}}); + rEventSelection.add("htrackscheck_v0_daughters", "htrackscheck_v0_daughters", kTH1I, {{15, 0, 15}}); hMChists.add("events_check", "No. of events in the generated MC", kTH1I, {{20, 0, 20}}); hMChists.add("events_checkrec", "No. of events in the reconstructed MC", kTH1I, {{25, 0, 25}}); @@ -282,7 +282,7 @@ struct HigherMassResonances { hv0DauLabel->GetXaxis()->SetBinLabel(7, "Eta"); hv0DauLabel->GetXaxis()->SetBinLabel(8, "PID TPC"); - std::shared_ptr hv0labelmcrec = rEventSelection.get(HIST("events_checkrec")); + std::shared_ptr hv0labelmcrec = hMChists.get(HIST("events_checkrec")); hv0labelmcrec->GetXaxis()->SetBinLabel(1, "All Tracks"); hv0labelmcrec->GetXaxis()->SetBinLabel(2, "V0Daughter Sel."); hv0labelmcrec->GetXaxis()->SetBinLabel(3, "V0 Sel."); @@ -455,52 +455,52 @@ struct HigherMassResonances { if (config.correlation2Dhist) rKzeroShort.fill(HIST("mass_lambda_kshort_before"), candidate.mK0Short(), candidate.mLambda()); - hglue.fill(HIST("htrackscheck_v0"), 0.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 0.5); if (config.isApplyDCAv0topv && std::fabs(candidate.dcav0topv()) > config.cMaxV0DCA) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 1.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 1.5); if (std::abs(candidate.rapidity(0)) >= config.confKsrapidity) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 2.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 2.5); if (pT < config.confV0PtMin) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 3.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 3.5); if (dcaDaughv0 > config.confV0DCADaughMax) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 4.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 4.5); if (cpav0 < config.confV0CPAMin) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 5.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 5.5); if (tranRad < config.confV0TranRadV0Min) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 6.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 6.5); if (tranRad > config.confV0TranRadV0Max) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 7.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 7.5); if (std::fabs(ctauK0s) > config.cMaxV0LifeTime) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 8.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 8.5); if (config.isapplyCompetingcut && (std::abs(candidate.mLambda() - o2::constants::physics::MassLambda0) <= config.competingcascrejlambda || std::abs(candidate.mAntiLambda() - o2::constants::physics::MassLambda0) <= config.competingcascrejlambda)) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 9.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 9.5); if (config.correlation2Dhist) rKzeroShort.fill(HIST("mass_lambda_kshort_after10"), candidate.mK0Short(), candidate.mLambda()); @@ -512,12 +512,12 @@ struct HigherMassResonances { if (config.isStandardV0 && candidate.v0Type() != 1) { return false; // Only standard V0s are selected } - hglue.fill(HIST("htrackscheck_v0"), 10.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 10.5); if (candidate.mK0Short() < lowmasscutks0 || candidate.mK0Short() > highmasscutks0) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 11.5); + rEventSelection.fill(HIST("htrackscheck_v0"), 11.5); return true; } @@ -533,44 +533,44 @@ struct HigherMassResonances { const auto tpcNClsF = track.tpcNClsFound(); const auto sign = track.sign(); - hglue.fill(HIST("htrackscheck_v0_daughters"), 0.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 0.5); if (config.hasTPC && !track.hasTPC()) return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 1.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 1.5); if (track.tpcNClsCrossedRows() < config.tpcCrossedrows) return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 2.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 2.5); if (track.tpcCrossedRowsOverFindableCls() < config.tpcCrossedrowsOverfcls) return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 3.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 3.5); if (tpcNClsF < config.confDaughTPCnclsMin) { return false; } - hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 4.5); if (charge < 0 && sign > 0) { return false; } - hglue.fill(HIST("htrackscheck_v0_daughters"), 5.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 5.5); if (charge > 0 && sign < 0) { return false; } - hglue.fill(HIST("htrackscheck_v0_daughters"), 6.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 6.5); if (std::abs(eta) > config.confDaughEta) { return false; } - hglue.fill(HIST("htrackscheck_v0_daughters"), 7.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 7.5); if (std::abs(nsigmaV0DaughterTPC) > config.confDaughPIDCutTPC) { return false; } - hglue.fill(HIST("htrackscheck_v0_daughters"), 8.5); + rEventSelection.fill(HIST("htrackscheck_v0_daughters"), 8.5); // if (std::abs()) @@ -887,8 +887,12 @@ struct HigherMassResonances { } PROCESS_SWITCH(HigherMassResonances, processSE, "same event process", true); - using EventCandidatesDerivedData = soa::Join; - using V0CandidatesDerivedData = soa::Join; + // using EventCandidates = soa::Filtered>; + // using TrackCandidates = soa::Filtered>; + // using V0TrackCandidate = aod::V0Datas; + + using EventCandidatesDerivedData = soa::Join; + using V0CandidatesDerivedData = soa::Join; using DauTracks = soa::Join; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for ME mixing"}; @@ -1280,7 +1284,7 @@ struct HigherMassResonances { } PROCESS_SWITCH(HigherMassResonances, processRec, "Process Reconstructed", false); - void processSEderived(EventCandidatesDerivedData::iterator const& collision, TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s) + void processSEderived(EventCandidatesDerivedData::iterator const& collision, V0CandidatesDerivedData const& V0s) { if (config.cSelectMultEstimator == kFT0M) { multiplicity = collision.centFT0M(); @@ -1319,22 +1323,22 @@ struct HigherMassResonances { continue; } - auto postrack1 = v1.template posTrack_as(); - auto negtrack1 = v1.template negTrack_as(); - auto postrack2 = v2.template posTrack_as(); - auto negtrack2 = v2.template negTrack_as(); + // auto postrack1 = v1.template posTrack_as(); + // auto negtrack1 = v1.template negTrack_as(); + // auto postrack2 = v2.template posTrack_as(); + // auto negtrack2 = v2.template negTrack_as(); - double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; - double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; - double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; - double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; + // double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; + // double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; + // double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; + // double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; - if (!(isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, v1) && isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, v1))) { - continue; - } - if (!(isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, v2) && isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, v2))) { - continue; - } + // if (!(isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, v1) && isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, v1))) { + // continue; + // } + // if (!(isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, v2) && isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, v2))) { + // continue; + // } if (std::find(v0indexes.begin(), v0indexes.end(), v1.globalIndex()) == v0indexes.end()) { v0indexes.push_back(v1.globalIndex()); @@ -1356,12 +1360,12 @@ struct HigherMassResonances { // rKzeroShort.fill(HIST("positive_phi"), postrack1.phi()); // } - if (postrack1.globalIndex() == postrack2.globalIndex()) { - continue; - } - if (negtrack1.globalIndex() == negtrack2.globalIndex()) { - continue; - } + // if (postrack1.globalIndex() == postrack2.globalIndex()) { + // continue; + // } + // if (negtrack1.globalIndex() == negtrack2.globalIndex()) { + // continue; + // } if (!applyAngSep(v1, v2)) { continue; diff --git a/PWGLF/Tasks/Resonances/k892analysis.cxx b/PWGLF/Tasks/Resonances/k892analysis.cxx index 34e4cc662a0..f095fcb3d9a 100644 --- a/PWGLF/Tasks/Resonances/k892analysis.cxx +++ b/PWGLF/Tasks/Resonances/k892analysis.cxx @@ -15,19 +15,23 @@ /// /// \author Bong-Hwi Lim , Sawan Sawan -#include -#include "TF1.h" -#include "TRandom3.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/Utils/inelGt.h" -#include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Framework/AnalysisTask.h" +#include "Common/DataModel/PIDResponse.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPObject.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "DataFormatsParameters/GRPObject.h" -#include "CommonConstants/PhysicsConstants.h" + +#include "TF1.h" +#include "TRandom3.h" +#include using namespace o2; using namespace o2::framework; @@ -59,6 +63,9 @@ struct K892analysis { Configurable invmass1D{"invmass1D", false, "Invariant mass 1D"}; Configurable studyAntiparticle{"studyAntiparticle", false, "Study anti-particles separately"}; Configurable fillPidPlots{"fillPidPlots", false, "Make TPC and TOF PID plots"}; + Configurable cisInelGt0{"cisInelGt0", true, "check if INEL>0"}; + Configurable cMCCent{"cMCCent", true, "Using calibrated MC centrality (for FT0M)"}; + // Configurable applyOccupancyCut{"applyOccupancyCut", false, "Apply occupancy cut"}; // Configurable occupancyCut{"occupancyCut", 1000, "Mimimum Occupancy cut"}; @@ -426,11 +433,11 @@ struct K892analysis { return false; } - template - void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2) + template + void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2, const Multdatamc& multiplicity) { // auto multNTracksPV = collision.multNTracksPV(); - auto multiplicity = collision.cent(); + // auto multiplicity = collision.cent(); if (additionalEvsel && !eventSelected(collision, multiplicity)) { return; } @@ -703,28 +710,105 @@ struct K892analysis { } } - void processDataLight(aod::ResoCollision const& collision, - aod::ResoTracks const& resotracks) + void processDataLight(aod::ResoCollision const& resocollisions, aod::ResoCollisionColls const& collisionIndex, soa::Join const& collisions, aod::ResoTracks const& resotracks) { // LOG(info) << "new collision, zvtx: " << collision.posZ(); + if (cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resocollisions.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision + + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + } if (additionalQAeventPlots) histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); - fillHistograms(collision, resotracks, resotracks); + auto multiplicity = resocollisions.cent(); + fillHistograms(resocollisions, resotracks, resotracks, multiplicity); } PROCESS_SWITCH(K892analysis, processDataLight, "Process Event for data", false); - void processMCLight(ResoMCCols::iterator const& collision, - soa::Join const& resotracks) + void processMCLight(ResoMCCols::iterator const& resoCollision, + aod::ResoCollisionColls const& collisionIndex, + soa::Join const& collisionsMC, + soa::Join const& resoTracks, + soa::Join const&) { - if (!collision.isInAfterAllCuts() || (std::abs(collision.posZ()) > cZvertCutMC)) // MC event selection, all cuts missing vtx cut + float multiplicity; + if (cMCCent && cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else if (!cMCCent && cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + + multiplicity = resoCollision.cent(); + } else if (cMCCent && !cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else { + multiplicity = resoCollision.cent(); + } + if (!resoCollision.isInAfterAllCuts() || (std::abs(resoCollision.posZ()) > cZvertCutMC)) // MC event selection, all cuts missing vtx cut return; - fillHistograms(collision, resotracks, resotracks); + fillHistograms(resoCollision, resoTracks, resoTracks, multiplicity); } PROCESS_SWITCH(K892analysis, processMCLight, "Process Event for MC (Reconstructed)", false); - void processMCTrue(ResoMCCols::iterator const& collision, aod::ResoMCParents const& resoParents) + void processMCTrue(ResoMCCols::iterator const& resoCollision, aod::ResoCollisionColls const& collisionIndex, aod::ResoMCParents const& resoParents, aod::ResoCollisionCandidatesMC const& collisionsMC, soa::Join const&) { - auto multiplicity = collision.cent(); + float multiplicity; + if (cMCCent && cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else if (!cMCCent && cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + + multiplicity = resoCollision.cent(); + } else if (cMCCent && !cisInelGt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else { + multiplicity = resoCollision.cent(); + } for (const auto& part : resoParents) { // loop over all pre-filtered MC particles if (std::abs(part.pdgCode()) != 313 || std::abs(part.y()) >= 0.5) continue; @@ -734,28 +818,28 @@ struct K892analysis { if (!pass1 || !pass2) continue; - if (collision.isVtxIn10()) // INEL10 + if (resoCollision.isVtxIn10()) // INEL10 { if (part.pdgCode() > 0) histos.fill(HIST("k892Gen"), 0, part.pt(), multiplicity); else histos.fill(HIST("k892GenAnti"), 0, part.pt(), multiplicity); } - if (collision.isVtxIn10() && collision.isInSel8()) // INEL>10, vtx10 + if (resoCollision.isVtxIn10() && resoCollision.isInSel8()) // INEL>10, vtx10 { if (part.pdgCode() > 0) histos.fill(HIST("k892Gen"), 1, part.pt(), multiplicity); else histos.fill(HIST("k892GenAnti"), 1, part.pt(), multiplicity); } - if (collision.isVtxIn10() && collision.isTriggerTVX()) // vtx10, TriggerTVX + if (resoCollision.isVtxIn10() && resoCollision.isTriggerTVX()) // vtx10, TriggerTVX { if (part.pdgCode() > 0) histos.fill(HIST("k892Gen"), 2, part.pt(), multiplicity); else histos.fill(HIST("k892GenAnti"), 2, part.pt(), multiplicity); } - if (collision.isInAfterAllCuts()) // after all event selection + if (resoCollision.isInAfterAllCuts()) // after all event selection { if (part.pdgCode() > 0) histos.fill(HIST("k892Gen"), 3, part.pt(), multiplicity); @@ -775,9 +859,10 @@ struct K892analysis { SameKindPair pairs{colBinning, nEvtMixing, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + auto multiplicity = collision1.cent(); if (additionalQAeventPlots) histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); - fillHistograms(collision1, tracks1, tracks2); + fillHistograms(collision1, tracks1, tracks2, multiplicity); } }; PROCESS_SWITCH(K892analysis, processMELight, "Process EventMixing light without partition", false); diff --git a/PWGLF/Tasks/Resonances/kstarInOO.cxx b/PWGLF/Tasks/Resonances/kstarInOO.cxx index d17c9e87110..e91bfb19251 100644 --- a/PWGLF/Tasks/Resonances/kstarInOO.cxx +++ b/PWGLF/Tasks/Resonances/kstarInOO.cxx @@ -80,7 +80,7 @@ struct kstarInOO { Configurable cfgTrackMaxDCAzToPVcut{"cfgTrackMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; Configurable cfgTrackPrimaryTrack{"cfgTrackPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz Configurable cfgTrackConnectedToPV{"cfgTrackConnectedToPV", true, "PV contributor track selection"}; // PV Contriuibutor - Configurable cfgGlobalTrack{"cfgGlobalTrack", false, "Global track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgGlobalTrack{"cfgGlobalTrack", true, "Global track selection"}; // kGoldenChi2 | kDCAxy | kDCAz Configurable cfgTrackGlobalWoDCATrack{"cfgTrackGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) // TPC Configurable cfgTracknFindableTPCClusters{"cfgTrackFindableTPCClusters", 50, "nFindable TPC Clusters"}; @@ -114,6 +114,9 @@ struct kstarInOO { Configurable cfgMinvMin{"cfgMinvMin", 0.60, "Minimum Minv value"}; Configurable cfgMinvMax{"cfgMinvMax", 1.20, "Maximum Minv value"}; + ConfigurableAxis binsDCAz{"binsDCAz", {40, -0.2, 0.2}, ""}; + ConfigurableAxis binsDCAxy{"binsDCAxy", {40, -0.2, 0.2}, ""}; + // Histogram Configurable cfgEventCutQA{"cfgEventCutsQA", false, "Enable Event QA Hists"}; Configurable cfgTrackCutQA{"cfgTrackCutQA", false, "Enable Track QA Hists"}; @@ -128,37 +131,54 @@ struct kstarInOO { const AxisSpec ptAxis = {200, 0, 20.0}; const AxisSpec pidAxis = {120, -6, 6}; const AxisSpec minvAxis = {cfgMinvNBins, cfgMinvMin, cfgMinvMax}; + const AxisSpec axisDCAz{binsDCAz, "DCA_{z}"}; + const AxisSpec axisDCAxy{binsDCAxy, "DCA_{XY}"}; if (cfgEventCutQA) { - histos.add("hPosZ_BC", "hPosZ_Bc", kTH1F, {{100, 0.0, 15.0}}); - histos.add("hPosZ_AC", "hPosZ_AC", kTH1F, {{100, 0.0, 15.0}}); + histos.add("hPosZ_BC", "hPosZ_Bc", kTH1F, {{300, -15.0, 15.0}}); + histos.add("hPosZ_AC", "hPosZ_AC", kTH1F, {{300, -15.0, 15.0}}); + histos.add("hcentFT0C_BC", "centFT0C_BC", kTH1F, {{110, 0.0, 110.0}}); + histos.add("hcentFT0C_AC", "centFT0C_AC", kTH1F, {{110, 0.0, 110.0}}); } if (cfgTrackCutQA) { - // histos.add("h_eta", "h_eta", kTH1F, {axisEta}); - // histos.add("h_phi", "h_phi", kTH1F, {axisPhi}); - + histos.add("hDCArToPv_BC", "DCArToPv_BC", kTH1F, {axisDCAxy}); + histos.add("hDCAzToPv_BC", "DCAzToPv_BC", kTH1F, {axisDCAz}); + histos.add("hIsPrim_BC", "hIsPrim_BC", kTH1F, {{2, -0.5, 1.5}}); + histos.add("hIsGood_BC", "hIsGood_BC", kTH1F, {{2, -0.5, 1.5}}); + histos.add("hIsPrimCont_BC", "hIsPrimCont_BC", kTH1F, {{2, -0.5, 1.5}}); + histos.add("hFindableTPCClusters_BC", "hFindableTPCClusters_BC", kTH1F, {{200, 0, 200}}); + histos.add("hFindableTPCRows_BC", "hFindableTPCRows_BC", kTH1F, {{200, 0, 200}}); + histos.add("hClustersVsRows_BC", "hClustersVsRows_BC", kTH1F, {{200, 0, 2}}); + histos.add("hTPCChi2_BC", "hTPCChi2_BC", kTH1F, {{200, 0, 100}}); histos.add("QA_nSigma_pion_TPC_BC", "QA_nSigma_pion_TPC_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_nSigma_pion_TOF_BC", "QA_nSigma_pion_TOF_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_pion_TPC_TOF_BC", "QA_pion_TPC_TOF_BC", {HistType::kTH2F, {pidAxis, pidAxis}}); - - histos.add("QA_nSigma_pion_TPC_AC", "QA_nSigma_pion_TPC_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); - histos.add("QA_nSigma_pion_TOF_AC", "QA_nSigma_pion_TOF_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); - histos.add("QA_pion_TPC_TOF_AC", "QA_pion_TPC_TOF_AC", {HistType::kTH2F, {pidAxis, pidAxis}}); - histos.add("QA_nSigma_kaon_TPC_BC", "QA_nSigma_kaon_TPC_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_nSigma_kaon_TOF_BC", "QA_nSigma_kaon_TOF_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_kaon_TPC_TOF_BC", "QA_kaon_TPC_TOF_BC", {HistType::kTH2F, {pidAxis, pidAxis}}); - + histos.add("QA_track_pT_BC", "QA_track_pT_BC", kTH1F, {{13, 0.0, 13.0}}); + + histos.add("hDCArToPv_AC", "DCArToPv_AC", kTH1F, {axisDCAxy}); + histos.add("hDCAzToPv_AC", "DCAzToPv_AC", kTH1F, {axisDCAz}); + histos.add("hIsPrim_AC", "hIsPrim_AC", kTH1F, {{2, -0.5, 1.5}}); + histos.add("hIsGood_AC", "hIsGood_AC", kTH1F, {{2, -0.5, 1.5}}); + histos.add("hIsPrimCont_AC", "hIsPrimCont_AC", kTH1F, {{2, -0.5, 1.5}}); + histos.add("hFindableTPCClusters_AC", "hFindableTPCClusters_AC", kTH1F, {{200, 0, 200}}); + histos.add("hFindableTPCRows_AC", "hFindableTPCRows_AC", kTH1F, {{200, 0, 200}}); + histos.add("hClustersVsRows_AC", "hClustersVsRows_AC", kTH1F, {{200, 0, 2}}); + histos.add("hTPCChi2_AC", "hTPCChi2_AC", kTH1F, {{200, 0, 100}}); + histos.add("QA_nSigma_pion_TPC_AC", "QA_nSigma_pion_TPC_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_nSigma_pion_TOF_AC", "QA_nSigma_pion_TOF_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_pion_TPC_TOF_AC", "QA_pion_TPC_TOF_AC", {HistType::kTH2F, {pidAxis, pidAxis}}); histos.add("QA_nSigma_kaon_TPC_AC", "QA_nSigma_kaon_TPC_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_nSigma_kaon_TOF_AC", "QA_nSigma_kaon_TOF_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_kaon_TPC_TOF_AC", "QA_kaon_TPC_TOF_AC", {HistType::kTH2F, {pidAxis, pidAxis}}); + histos.add("QA_track_pT_AC", "QA_track_pT_AC", kTH1F, {{13, 0.0, 13.0}}); } if (cfgDataHistos) { histos.add("nEvents", "nEvents", kTH1F, {{4, 0.0, 4.0}}); - histos.add("nEvents_Mix", "nEvents_Mix", kTH1F, {{4, 0.0, 4.0}}); - histos.add("hUSS", "hUSS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); histos.add("hLSS", "hLSS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); histos.add("hUSS_Mix", "hUSS_Mix", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); @@ -167,7 +187,6 @@ struct kstarInOO { if (cfgMcHistos) { histos.add("nEvents_MC", "nEvents_MC", kTH1F, {{4, 0.0, 4.0}}); - histos.add("nEvents_MC_Mix", "nEvents_MC_Mix", kTH1F, {{4, 0.0, 4.0}}); histos.add("nEvents_MC_True", "nEvents_MC_True", kTH1F, {{4, 0.0, 4.0}}); histos.add("hMC_USS", "hMC_USS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); @@ -177,7 +196,6 @@ struct kstarInOO { histos.add("hMC_USS_True", "hMC_USS_True", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); histos.add("hMC_kstar_True", "hMC_kstar_True", kTHnSparseF, {cfgCentAxis, ptAxis}); } - } // end of init using EventCandidates = soa::Join; //, aod::CentFT0Ms, aod::CentFT0As @@ -206,11 +224,12 @@ struct kstarInOO { //|| //================================== template - bool eventSelection(const EventType event) + bool eventSelection(const EventType event, const bool QA) { - if (cfgEventCutQA) + if (cfgEventCutQA && QA) { histos.fill(HIST("hPosZ_BC"), event.posZ()); - + histos.fill(HIST("hcentFT0C_BC"), event.centFT0C()); + } if (!event.sel8()) return false; if (std::abs(event.posZ()) > cfgEventVtxCut) @@ -226,67 +245,133 @@ struct kstarInOO { if (!event.selection_bit(aod::evsel::kNoCollInTimeRangeStandard)) return false; - if (cfgEventCutQA) + if (cfgEventCutQA && QA) { histos.fill(HIST("hPosZ_AC"), event.posZ()); - + histos.fill(HIST("hcentFT0C_AC"), event.centFT0C()); + } return true; }; template - bool trackSelection(const TracksType track) + bool trackSelection(const TracksType track, bool QA) { + if (cfgTrackCutQA && QA) { + histos.fill(HIST("hDCArToPv_BC"), track.dcaXY()); + histos.fill(HIST("hDCAzToPv_BC"), track.dcaZ()); + histos.fill(HIST("hIsPrim_BC"), track.isPrimaryTrack()); + histos.fill(HIST("hIsGood_BC"), track.isGlobalTrackWoDCA()); + histos.fill(HIST("hIsPrimCont_BC"), track.isPVContributor()); + histos.fill(HIST("hFindableTPCClusters_BC"), track.tpcNClsFindable()); + histos.fill(HIST("hFindableTPCRows_BC"), track.tpcNClsCrossedRows()); + histos.fill(HIST("hClustersVsRows_BC"), track.tpcCrossedRowsOverFindableCls()); + histos.fill(HIST("hTPCChi2_BC"), track.tpcChi2NCl()); + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } + if (track.pt() < cfgTrackMinPt) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (std::abs(track.eta()) > cfgTrackMaxEta) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } - if (cfgGlobalTrack && !track.isGlobalTrack()) + if (!cfgGlobalTrack && !track.isGlobalTrack()) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (std::abs(track.dcaXY()) > cfgTrackMaxDCArToPVcut) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (std::abs(track.dcaZ()) > cfgTrackMaxDCAzToPVcut) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (cfgTrackPrimaryTrack && !track.isPrimaryTrack()) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (cfgTrackGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (track.tpcNClsFindable() < cfgTracknFindableTPCClusters) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (track.tpcNClsCrossedRows() < cfgTracknTPCCrossedRows) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (track.tpcCrossedRowsOverFindableCls() > cfgTracknRowsOverFindable) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (track.tpcChi2NCl() > cfgTracknTPCChi2) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (track.itsChi2NCl() > cfgTracknITSChi2) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } if (cfgTrackConnectedToPV && !track.isPVContributor()) return false; + if (cfgTrackCutQA && QA) { + histos.fill(HIST("QA_track_pT_BC"), track.pt()); + } + if (cfgTrackCutQA && QA) { + histos.fill(HIST("hDCArToPv_AC"), track.dcaXY()); + histos.fill(HIST("hDCAzToPv_AC"), track.dcaZ()); + histos.fill(HIST("hIsPrim_AC"), track.isPrimaryTrack()); + histos.fill(HIST("hIsGood_AC"), track.isGlobalTrackWoDCA()); + histos.fill(HIST("hIsPrimCont_AC"), track.isPVContributor()); + histos.fill(HIST("hFindableTPCClusters_AC"), track.tpcNClsFindable()); + histos.fill(HIST("hFindableTPCRows_AC"), track.tpcNClsCrossedRows()); + histos.fill(HIST("hClustersVsRows_AC"), track.tpcCrossedRowsOverFindableCls()); + histos.fill(HIST("hTPCChi2_AC"), track.tpcChi2NCl()); + histos.fill(HIST("QA_track_pT_AC"), track.pt()); + } return true; }; template - bool trackPIDKaon(const TrackPID& candidate) + bool trackPIDKaon(const TrackPID& candidate, const bool QA) { bool tpcPIDPassed{false}, tofPIDPassed{false}; - // TPC - if (cfgTrackCutQA) { + if (cfgTrackCutQA && QA) { + // kaon histos.fill(HIST("QA_nSigma_kaon_TPC_BC"), candidate.pt(), candidate.tpcNSigmaKa()); histos.fill(HIST("QA_nSigma_kaon_TOF_BC"), candidate.pt(), candidate.tofNSigmaKa()); histos.fill(HIST("QA_kaon_TPC_TOF_BC"), candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()); } + // TPC if (std::abs(candidate.tpcNSigmaKa()) < cfgTrackTPCPIDnSig) tpcPIDPassed = true; @@ -301,7 +386,8 @@ struct kstarInOO { // TPC & TOF if (tpcPIDPassed && tofPIDPassed) { - if (cfgTrackCutQA) { + if (cfgTrackCutQA && QA) { + // kaon histos.fill(HIST("QA_nSigma_kaon_TPC_AC"), candidate.pt(), candidate.tpcNSigmaKa()); histos.fill(HIST("QA_nSigma_kaon_TOF_AC"), candidate.pt(), candidate.tofNSigmaKa()); histos.fill(HIST("QA_kaon_TPC_TOF_AC"), candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()); @@ -312,18 +398,20 @@ struct kstarInOO { } template - bool trackPIDPion(const TrackPID& candidate) + bool trackPIDPion(const TrackPID& candidate, const bool QA) { bool tpcPIDPassed{false}, tofPIDPassed{false}; - // TPC - if (cfgTrackCutQA) { + if (cfgTrackCutQA && QA) { + // pion histos.fill(HIST("QA_nSigma_pion_TPC_BC"), candidate.pt(), candidate.tpcNSigmaPi()); histos.fill(HIST("QA_nSigma_pion_TOF_BC"), candidate.pt(), candidate.tofNSigmaPi()); histos.fill(HIST("QA_pion_TPC_TOF_BC"), candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()); } + + // TPC if (std::abs(candidate.tpcNSigmaPi()) < cfgTrackTPCPIDnSig) tpcPIDPassed = true; - + // TOF if (candidate.hasTOF()) { if (std::abs(candidate.tofNSigmaPi()) < cfgTrackTOFPIDnSig) { tofPIDPassed = true; @@ -334,7 +422,8 @@ struct kstarInOO { // TPC & TOF if (tpcPIDPassed && tofPIDPassed) { - if (cfgTrackCutQA) { + if (cfgTrackCutQA && QA) { + // pion histos.fill(HIST("QA_nSigma_pion_TPC_AC"), candidate.pt(), candidate.tpcNSigmaPi()); histos.fill(HIST("QA_nSigma_pion_TOF_AC"), candidate.pt(), candidate.tofNSigmaPi()); histos.fill(HIST("QA_pion_TPC_TOF_AC"), candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()); @@ -345,20 +434,14 @@ struct kstarInOO { } template - void TrackSlicing(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool IsMix) + void TrackSlicing(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool QA, const bool IsMix) { auto tracks1 = kaon->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); auto tracks2 = pion->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); auto centrality = collision1.centFT0C(); for (const auto& [trk1, trk2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - - if (!trackSelection(trk1) || !trackSelection(trk2)) - continue; - if (!trackPIDKaon(trk1) || !trackPIDPion(trk2)) - continue; - - auto [KstarPt, Minv] = minvReconstruction(trk1, trk2); + auto [KstarPt, Minv] = minvReconstruction(trk1, trk2, QA); if (Minv < 0) continue; @@ -382,20 +465,14 @@ struct kstarInOO { } // TrackSlicing template - void TrackSlicingMC(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool IsMix) + void TrackSlicingMC(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool QA, const bool IsMix) { auto tracks1 = kaonMC->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); auto tracks2 = pionMC->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); auto centrality = collision1.centFT0C(); for (const auto& [trk1, trk2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - - if (!trackSelection(trk1) || !trackSelection(trk2)) - continue; - if (!trackPIDKaon(trk1) || !trackPIDPion(trk2)) - continue; - - auto [KstarPt, Minv] = minvReconstruction(trk1, trk2); + auto [KstarPt, Minv] = minvReconstruction(trk1, trk2, QA); if (Minv < 0) continue; @@ -420,6 +497,7 @@ struct kstarInOO { // Gen MC if (!trk1.has_mcParticle() || !trk2.has_mcParticle()) continue; + auto particle1 = trk1.mcParticle(); auto particle2 = trk2.mcParticle(); if (std::fabs(particle1.pdgCode()) != 321) @@ -462,14 +540,13 @@ struct kstarInOO { } // TrackSlicingMC template - std::pair minvReconstruction(const TracksType& trk1, const TracksType& trk2) + std::pair minvReconstruction(const TracksType& trk1, const TracksType& trk2, const bool QA) { TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance; - if (!trackSelection(trk1) || !trackSelection(trk2)) + if (!trackSelection(trk1, QA) || !trackSelection(trk2, QA)) return {-1.0, -1.0}; - - if (!trackPIDKaon(trk1) || !trackPIDPion(trk2)) + if (!trackPIDKaon(trk1, QA) || !trackPIDPion(trk2, QA)) return {-1.0, -1.0}; if (trk1.globalIndex() == trk2.globalIndex()) { @@ -502,7 +579,7 @@ struct kstarInOO { } } - auto goodEv = eventSelection(collision); + auto goodEv = eventSelection(collision, true); if (cfgDataHistos) { histos.fill(HIST("nEvents"), 0.5); } @@ -511,17 +588,19 @@ struct kstarInOO { bool INELgt0 = false; for (const auto& track : tracks) { + if (!trackSelection(track, true)) + continue; if (std::fabs(track.eta()) < cfgTrackMaxEta) { INELgt0 = true; - break; } } if (!INELgt0) return; + if (cfgDataHistos) { histos.fill(HIST("nEvents"), 1.5); } - TrackSlicing(collision, tracks, collision, tracks, false); + TrackSlicing(collision, tracks, collision, tracks, true, false); } // processSameEvents PROCESS_SWITCH(kstarInOO, processDataSameEvent, "process Data Same Event", false); @@ -545,19 +624,13 @@ struct kstarInOO { std::cout << "Processed DATA Mixed Events : " << nEventsMix << std::endl; } } - auto goodEv1 = eventSelection(collision1); - auto goodEv2 = eventSelection(collision2); - if (cfgDataHistos) { - histos.fill(HIST("nEvents_Mix"), 0.5); - } + auto goodEv1 = eventSelection(collision1, false); + auto goodEv2 = eventSelection(collision2, false); if (!goodEv1 || !goodEv2) continue; - if (cfgDataHistos) { - histos.fill(HIST("nEvents_Mix"), 1.5); - } - TrackSlicing(collision1, tracks1, collision2, tracks2, true); + TrackSlicing(collision1, tracks1, collision2, tracks2, false, true); } } PROCESS_SWITCH(kstarInOO, processDataMixedEvent, "process DATA Mixed Event", false); @@ -580,7 +653,7 @@ struct kstarInOO { } } - auto goodEv = eventSelection(collision); + auto goodEv = eventSelection(collision, true); if (cfgMcHistos) { histos.fill(HIST("nEvents_MC"), 0.5); } @@ -591,7 +664,6 @@ struct kstarInOO { for (const auto& track : tracks) { if (std::fabs(track.eta()) < cfgTrackMaxEta) { INELgt0 = true; - break; } } if (!INELgt0) @@ -600,10 +672,10 @@ struct kstarInOO { if (cfgMcHistos) { histos.fill(HIST("nEvents_MC"), 1.5); } - TrackSlicingMC(collision, tracks, collision, tracks, false); + TrackSlicingMC(collision, tracks, collision, tracks, true, false); } // processSameEvents_MC - PROCESS_SWITCH(kstarInOO, processMCSameEvent, "process MC Same Event", false); + PROCESS_SWITCH(kstarInOO, processMCSameEvent, "process MC Same Event", true); //======================================================= //| @@ -624,19 +696,11 @@ struct kstarInOO { std::cout << "Processed MC Mixed Events : " << nEventsMCMix << std::endl; } } - auto goodEv1 = eventSelection(collision1); - auto goodEv2 = eventSelection(collision2); - if (cfgMcHistos) { - histos.fill(HIST("nEvents_MC_Mix"), 0.5); - } - + auto goodEv1 = eventSelection(collision1, false); + auto goodEv2 = eventSelection(collision2, false); if (!goodEv1 || !goodEv2) continue; - - if (cfgMcHistos) { - histos.fill(HIST("nEvents_MC_Mix"), 1.5); - } - TrackSlicingMC(collision1, tracks1, collision2, tracks2, true); + TrackSlicingMC(collision1, tracks1, collision2, tracks2, false, true); } // mixing } // processMixedEvent_MC PROCESS_SWITCH(kstarInOO, processMCMixedEvent, "process MC Mixed Event", false); @@ -652,14 +716,10 @@ struct kstarInOO { { if (cDebugLevel > 0) { ++nEventsTrue; - if ((nEventsTrue & 10000) == 0) { - std::cout << "Processed MC True Events : " << nEventsTrue << std::endl; - } } if (fabs(collision.posZ()) > cfgEventVtxCut) return; - if (recocolls.size() <= 0) { // not reconstructed if (cfgForceGenReco) { return; @@ -669,7 +729,7 @@ struct kstarInOO { double centrality = -1; for (auto& recocoll : recocolls) { centrality = recocoll.centFT0C(); - auto goodEv = eventSelection(recocoll); + auto goodEv = eventSelection(recocoll, false); if (cfgMcHistos) { histos.fill(HIST("nEvents_MC_True"), 0.5); diff --git a/PWGLF/Tasks/Resonances/kstarqa.cxx b/PWGLF/Tasks/Resonances/kstarqa.cxx index b4a6e3a2ee4..65cd50714d6 100644 --- a/PWGLF/Tasks/Resonances/kstarqa.cxx +++ b/PWGLF/Tasks/Resonances/kstarqa.cxx @@ -85,6 +85,7 @@ struct Kstarqa { Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", true, "kNoTimeFrameBorder"}; Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", true, "kNoITSROFrameBorder"}; Configurable isApplyParticleMID{"isApplyParticleMID", true, "Apply particle misidentification"}; + Configurable checkVzEvSigLoss{"checkVzEvSigLoss", false, "Check Vz event signal loss"}; Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; Configurable configOccCut{"configOccCut", 1000., "Occupancy cut"}; @@ -250,8 +251,8 @@ struct Kstarqa { hOthers.add("hCRFC_after", "CRFC after distribution", kTH1F, {{100, 0.0f, 10.0f}}); hOthers.add("hCRFC_before", "CRFC before distribution", kTH1F, {{100, 0.0f, 10.0f}}); - hOthers.add("hKstar_Rap", "Pair rapidity distribution; y; Counts", kTH1F, {{1000, -5.0f, 5.0f}}); - hOthers.add("hKstar_Eta", "Pair eta distribution; #eta; Counts", kTH1F, {{1000, -5.0f, 5.0f}}); + hOthers.add("hKstar_rap_pt", "Pair rapidity distribution; y; p_{T}; Counts", kTH2F, {{400, -2.0f, 2.0f}, ptAxis}); + hOthers.add("hKstar_eta_pt", "Pair eta distribution; #eta; p_{T}; Counts", kTH2F, {{400, -2.0f, 2.0f}, ptAxis}); hPID.add("Before/hNsigmaTPC_Ka_before", "N #sigma Kaon TPC before", kTH2F, {{50, 0.0f, 10.0f}, {100, -10.0f, 10.0f}}); hPID.add("Before/hNsigmaTOF_Ka_before", "N #sigma Kaon TOF before", kTH2F, {{50, 0.0f, 10.0f}, {100, -10.0f, 10.0f}}); @@ -328,7 +329,8 @@ struct Kstarqa { hInvMass.add("hAllRecCollisions", "All reconstructed events", kTH1F, {multiplicityAxis}); hInvMass.add("hAllRecCollisionsCalib", "All reconstructed events", kTH1F, {multiplicityAxis}); hInvMass.add("MCcorrections/hImpactParameterRec", "Impact parameter in reconstructed MC", kTH1F, {impactParAxis}); - hInvMass.add("MCcorrections/MultiplicityRec", "Multiplicity in reconstructed MC", kTH1F, {multiplicityAxis}); + hInvMass.add("MCcorrections/MultiplicityRec", "Multiplicity in generated MC with at least 1 reconstruction", kTH1F, {multiplicityAxis}); + hInvMass.add("MCcorrections/MultiplicityRec2", "Multiplicity in reconstructed MC", kTH1F, {multiplicityAxis}); hInvMass.add("MCcorrections/hImpactParameterGen", "Impact parameter in generated MC", kTH1F, {impactParAxis}); hInvMass.add("MCcorrections/MultiplicityGen", "Multiplicity in generated MC", kTH1F, {multiplicityAxis}); hInvMass.add("MCcorrections/hImpactParametervsMultiplicity", "Impact parameter vs multiplicity in reconstructed MC", kTH2F, {{impactParAxis}, {multiplicityAxis}}); @@ -375,8 +377,8 @@ struct Kstarqa { // hInvMass.add("multdist_FT0A", "FT0A Multiplicity distribution", kTH1F, {axisMultdist}); // hInvMass.add("multdist_FT0C", "FT0C Multiplicity distribution", kTH1F, {axisMultdist}); // hInvMass.add("hNcontributor", "Number of primary vertex contributor", kTH1F, {{2000, 0.0f, 10000.0f}}); - rEventSelection.add("hDcaxy", "Dcaxy distribution", kTH1F, {{200, -1.0f, 1.0f}}); - rEventSelection.add("hDcaz", "Dcaz distribution", kTH1F, {{200, -1.0f, 1.0f}}); + rEventSelection.add("hDcaxy_cent_pt", "Dcaxy distribution", kTH3F, {{200, -1.0f, 1.0f}, multiplicityAxis, ptAxis}); + rEventSelection.add("hDcaz_cent_pt", "Dcaz distribution", kTH3F, {{200, -1.0f, 1.0f}, multiplicityAxis, ptAxis}); } } @@ -385,7 +387,7 @@ struct Kstarqa { double massKa = o2::constants::physics::MassKPlus; template - bool selectionEvent(const Coll& collision, bool fillHist = true) + bool selectionEvent(const Coll& collision, bool fillHist = false) // default to false { if (fillHist) rEventSelection.fill(HIST("hEventCut"), 0); @@ -935,7 +937,7 @@ struct Kstarqa { int occupancy = collision.trackOccupancyInTimeRange(); rEventSelection.fill(HIST("hOccupancy"), occupancy); - if (!selectionEvent(collision, true)) { + if (!selectionEvent(collision, true)) { // fill data event cut histogram return; } @@ -1017,8 +1019,8 @@ struct Kstarqa { } if (cQAevents) { - rEventSelection.fill(HIST("hDcaxy"), track1.dcaXY()); - rEventSelection.fill(HIST("hDcaz"), track1.dcaZ()); + rEventSelection.fill(HIST("hDcaxy_cent_pt"), track1.dcaXY(), multiplicity, track1.pt()); + rEventSelection.fill(HIST("hDcaz_cent_pt"), track1.dcaZ(), multiplicity, track1.pt()); } // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion @@ -1093,8 +1095,8 @@ struct Kstarqa { continue; } - hOthers.fill(HIST("hKstar_Rap"), mother.Rapidity()); - hOthers.fill(HIST("hKstar_Eta"), mother.Eta()); + hOthers.fill(HIST("hKstar_rap_pt"), mother.Rapidity(), mother.Pt()); + hOthers.fill(HIST("hKstar_eta_pt"), mother.Eta(), mother.Pt()); isMix = false; fillInvMass(daughter1, daughter2, mother, multiplicity, isMix, track1, track2); @@ -1146,7 +1148,7 @@ struct Kstarqa { // if (!c1.sel8() || !c2.sel8()) // continue; - if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { + if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { // don't fill event cut histogram continue; } @@ -1212,7 +1214,7 @@ struct Kstarqa { auto runMixing = [&](auto& pair, auto multiplicityGetter) { for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { + if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { // don't fill event cut histogram continue; } @@ -1295,7 +1297,7 @@ struct Kstarqa { int occupancy = collision.trackOccupancyInTimeRange(); rEventSelection.fill(HIST("hOccupancy"), occupancy); - if (!selectionEvent(collision, false)) { + if (!selectionEvent(collision, false)) { // don't fill event cut histogram return; } @@ -1379,8 +1381,8 @@ struct Kstarqa { } if (cQAevents) { - rEventSelection.fill(HIST("hDcaxy"), track1.dcaXY()); - rEventSelection.fill(HIST("hDcaz"), track1.dcaZ()); + rEventSelection.fill(HIST("hDcaxy_cent_pt"), track1.dcaXY(), multiplicity, track1.pt()); + rEventSelection.fill(HIST("hDcaz_cent_pt"), track1.dcaZ(), multiplicity, track1.pt()); } // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion @@ -1481,8 +1483,8 @@ struct Kstarqa { continue; } - hOthers.fill(HIST("hKstar_Rap"), mother.Rapidity()); - hOthers.fill(HIST("hKstar_Eta"), mother.Eta()); + hOthers.fill(HIST("hKstar_rap_pt"), mother.Rapidity(), mother.Pt()); + hOthers.fill(HIST("hKstar_eta_pt"), mother.Eta(), mother.Pt()); isMix = false; fillInvMass(daughter1, daughter2, mother, multiplicity, isMix, track1, track2); @@ -1531,7 +1533,7 @@ struct Kstarqa { rEventSelection.fill(HIST("eventsCheckGen"), 2.5); for (const auto& collision : collisions) { - if (!selectionEvent(collision, true)) { + if (!selectionEvent(collision, false)) { // don't fill event cut histogram continue; } multiplicity = collision.centFT0M(); @@ -1639,18 +1641,27 @@ struct Kstarqa { return; } + if (selectionConfig.checkVzEvSigLoss && (std::abs(mcCollision.posZ()) >= selectionConfig.cutzvertex)) { + return; + } + auto impactPar = mcCollision.impactParameter(); - multiplicity = -1; - multiplicity = mcCollision.centFT0M(); + auto multiplicityRec = -1; + auto multiplicityGen = -1; + multiplicityGen = mcCollision.centFT0M(); hInvMass.fill(HIST("MCcorrections/hImpactParameterGen"), impactPar); - hInvMass.fill(HIST("MCcorrections/MultiplicityGen"), multiplicity); + hInvMass.fill(HIST("MCcorrections/MultiplicityGen"), multiplicityGen); bool isSelectedEvent = false; auto multiplicity1 = -999.; for (const auto& RecCollision : recCollisions) { - if (!selectionEvent(RecCollision, false)) + if (!RecCollision.has_mcCollision()) + continue; + if (!selectionEvent(RecCollision, false)) // don't fill event cut histogram continue; // multiplicity1 = RecCollision.centFT0M(); + const auto& mcCollisionRec = RecCollision.mcCollision_as(); + multiplicityRec = mcCollisionRec.centFT0M(); if (cSelectMultEstimator == kFT0M) { multiplicity1 = RecCollision.centFT0M(); @@ -1670,7 +1681,8 @@ struct Kstarqa { // Event loss if (isSelectedEvent) { hInvMass.fill(HIST("MCcorrections/hImpactParameterRec"), impactPar); - hInvMass.fill(HIST("MCcorrections/MultiplicityRec"), multiplicity); + hInvMass.fill(HIST("MCcorrections/MultiplicityRec"), multiplicityGen); + hInvMass.fill(HIST("MCcorrections/MultiplicityRec2"), multiplicityRec); hInvMass.fill(HIST("MCcorrections/hImpactParametervsMultiplicity"), impactPar, multiplicity1); } @@ -1680,15 +1692,15 @@ struct Kstarqa { continue; // signal loss estimation - hInvMass.fill(HIST("MCcorrections/hSignalLossDenominator"), mcPart.pt(), multiplicity); + hInvMass.fill(HIST("MCcorrections/hSignalLossDenominator"), mcPart.pt(), multiplicityGen); if (isSelectedEvent) { - hInvMass.fill(HIST("MCcorrections/hSignalLossNumerator"), mcPart.pt(), multiplicity); + hInvMass.fill(HIST("MCcorrections/hSignalLossNumerator"), mcPart.pt(), multiplicityGen); } } // end loop on gen particles } PROCESS_SWITCH(Kstarqa, processEvtLossSigLossMC, "Process Signal Loss, Event Loss", false); - void processRec(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, aod::McCollisions const&) + void processRec(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) { if (!collision.has_mcCollision()) { @@ -1705,8 +1717,6 @@ struct Kstarqa { } // multiplicity = collision.centFT0M(); - multiplicity = -1.0; - if (cSelectMultEstimator == kFT0M) { multiplicity = collision.centFT0M(); } else if (cSelectMultEstimator == kFT0A) { @@ -1722,13 +1732,17 @@ struct Kstarqa { hInvMass.fill(HIST("hAllRecCollisions"), multiplicity); hInvMass.fill(HIST("hAllRecCollisionsCalib"), multiplicityRec); - if (!selectionEvent(collision, false)) { + if (!selectionEvent(collision, true)) { // fill MC event cut histogram return; } hInvMass.fill(HIST("h1RecMult"), multiplicity); hInvMass.fill(HIST("h1RecMult2"), multiplicityRec); + if (cQAevents) { + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + } + auto oldindex = -999; for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { @@ -1739,6 +1753,11 @@ struct Kstarqa { continue; } + if (cQAevents) { + rEventSelection.fill(HIST("hDcaxy_cent_pt"), track1.dcaXY(), multiplicity, track1.pt()); + rEventSelection.fill(HIST("hDcaz_cent_pt"), track1.dcaZ(), multiplicity, track1.pt()); + } + auto track1ID = track1.index(); for (const auto& track2 : tracks) { rEventSelection.fill(HIST("recMCparticles"), 0.5); @@ -1767,7 +1786,12 @@ struct Kstarqa { const auto mctrack2 = track2.mcParticle(); int track1PDG = std::abs(mctrack1.pdgCode()); int track2PDG = std::abs(mctrack2.pdgCode()); - + if (cQAplots) { + hPID.fill(HIST("Before/hTPCnsigKa_mult_pt"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("Before/hTPCnsigPi_mult_pt"), track2.tpcNSigmaPi(), multiplicity, track2.pt()); + hPID.fill(HIST("Before/hTOFnsigKa_mult_pt"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("Before/hTOFnsigPi_mult_pt"), track2.tofNSigmaKa(), multiplicity, track2.pt()); + } if (cQAplots && (mctrack2.pdgCode() == PDG_t::kPiPlus)) { // pion hPID.fill(HIST("Before/h1PID_TPC_pos_pion"), track2.tpcNSigmaPi()); hPID.fill(HIST("Before/h1PID_TOF_pos_pion"), track2.tofNSigmaPi()); @@ -1896,6 +1920,12 @@ struct Kstarqa { continue; rEventSelection.fill(HIST("recMCparticles"), 13.5); } + if (cQAplots) { + hPID.fill(HIST("After/hTPCnsigKa_mult_pt"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("After/hTPCnsigPi_mult_pt"), track2.tpcNSigmaPi(), multiplicity, track2.pt()); + hPID.fill(HIST("After/hTOFnsigKa_mult_pt"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("After/hTOFnsigPi_mult_pt"), track2.tofNSigmaKa(), multiplicity, track2.pt()); + } if (selectionConfig.isApplyCutsOnMother) { if (mothertrack1.pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow @@ -1934,20 +1964,22 @@ struct Kstarqa { } PROCESS_SWITCH(Kstarqa, processRec, "Process Reconstructed", false); - void processRec2(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, aod::McCollisions const& /*mcCollisions*/) + void processRec2(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) { if (!collision.has_mcCollision()) { return; } + double multiplicityRec = -1.0; + const auto& mcCollisionRec = collision.mcCollision_as(); + multiplicityRec = mcCollisionRec.centFT0M(); + if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { return; } // multiplicity = collision.centFT0M(); - multiplicity = -1.0; - if (cSelectMultEstimator == kFT0M) { multiplicity = collision.centFT0M(); } else if (cSelectMultEstimator == kFT0A) { @@ -1961,50 +1993,14 @@ struct Kstarqa { } hInvMass.fill(HIST("hAllRecCollisions"), multiplicity); + hInvMass.fill(HIST("hAllRecCollisionsCalib"), multiplicityRec); - if (!selectionEvent(collision, false)) { + if (!selectionEvent(collision, false)) { // don't fill event cut histogram return; } - // // if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex || !collision.sel8()) { - // if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex) { - // return; - // } - - // if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - // return; - // } - - // if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { - // return; - // } - - // if (!collision.sel8()) { - // return; - // } - - // if (selectionConfig.isNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { - // return; - // } - // if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { - // return; - // } - - // multiplicity = collision.centFT0M(); - - multiplicity = -1.0; - - if (cSelectMultEstimator == kFT0M) { - multiplicity = collision.centFT0M(); - } else if (cSelectMultEstimator == kFT0A) { - multiplicity = collision.centFT0A(); - } else if (cSelectMultEstimator == kFT0C) { - multiplicity = collision.centFT0C(); - } else if (cSelectMultEstimator == kFV0A) { - multiplicity = collision.centFV0A(); - } else { - multiplicity = collision.centFT0M(); // default - } + hInvMass.fill(HIST("h1RecMult"), multiplicity); + hInvMass.fill(HIST("h1RecMult2"), multiplicityRec); hInvMass.fill(HIST("h1RecMult"), multiplicity); @@ -2169,6 +2165,7 @@ struct Kstarqa { mother = daughter1 + daughter2; // Kstar meson hInvMass.fill(HIST("h2KstarRecpt2"), mothertrack1.pt(), multiplicity, std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())); + hInvMass.fill(HIST("h2KstarRecptCalib2"), mothertrack1.pt(), multiplicityRec, std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())); if (applyRecMotherRapidity && mother.Rapidity() >= selectionConfig.rapidityMotherData) { continue; @@ -2176,6 +2173,7 @@ struct Kstarqa { hInvMass.fill(HIST("h1KstarRecMass"), mother.M()); hInvMass.fill(HIST("h2KstarRecpt1"), mother.Pt(), multiplicity, mother.M()); + hInvMass.fill(HIST("h2KstarRecptCalib1"), mother.Pt(), multiplicityRec, mother.M()); } } } diff --git a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx index 0348751dae9..fd7128850a0 100644 --- a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx @@ -187,9 +187,10 @@ struct Lambda1520analysisinpp { // switches Configurable cFillMultQA{"cFillMultQA", false, "Turn on/off additional QA plots"}; + Configurable cFillTrackQA{"cFillTrackQA", false, "Turn on/off additional QA plots"}; Configurable cFilladditionalQAeventPlots{"cFilladditionalQAeventPlots", false, "Additional QA event plots"}; Configurable cFilladditionalMEPlots{"cFilladditionalMEPlots", false, "Additional Mixed event plots"}; - Configurable cFilldeltaEtaPhiPlots{"cFilldeltaEtaPhiPlots", false, "Enamble additional cuts on daughters"}; + Configurable cFilldeltaEtaPhiPlots{"cFilldeltaEtaPhiPlots", false, "Enable additional cuts on daughters"}; Configurable cFill1DQAs{"cFill1DQAs", false, "Invariant mass 1D"}; Configurable centEstimator{"centEstimator", 0, "Select centrality estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C"}; @@ -201,22 +202,22 @@ struct Lambda1520analysisinpp { // Filter centralityFilter = nabs(aod::cent::centFT0C) <= cfg_Event_CentralityMax; // Filter triggerFilter = (o2::aod::evsel::sel8 == true); - Filter tofPIDFilter = aod::track::tofExpMom < 0.0f || ((aod::track::tofExpMom > 0.0f) && (/* (nabs(aod::pidtof::tofNSigmaPi) < configPID.pidnSigmaPreSelectionCut) || */ (nabs(aod::pidtof::tofNSigmaKa) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < configPID.pidnSigmaPreSelectionCut))); // TOF - Filter tpcPIDFilter = /* nabs(aod::pidtpc::tpcNSigmaPi) < configPID.pidnSigmaPreSelectionCut || */ nabs(aod::pidtpc::tpcNSigmaKa) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < configPID.pidnSigmaPreSelectionCut; // TPC - Filter trackFilter = (configTracks.trackSelection == AllTracks) || - ((configTracks.trackSelection == GlobalTracks) && requireGlobalTrackInFilter()) || - ((configTracks.trackSelection == GlobalTracksWoPtEta) && requireGlobalTrackWoPtEtaInFilter()) || - ((configTracks.trackSelection == GlobalTracksWoDCA) && requireGlobalTrackWoDCAInFilter()) || - ((configTracks.trackSelection == QualityTracks) && requireQualityTracksInFilter()) || - ((configTracks.trackSelection == InAcceptanceTracks) && requireTrackCutInFilter(TrackSelectionFlags::kInAcceptanceTracks)); - - Filter acceptanceFilter = (nabs(aod::track::eta) < configTracks.cfgCutEta && nabs(aod::track::pt) > configTracks.cMinPtcut); - // Filter DCAcutFilter = (nabs(aod::track::dcaXY) < configTracks.cfgCutDCAxy) && (nabs(aod::track::dcaZ) < configTracks.cfgCutDCAz); + Filter acceptanceFilter = (nabs(aod::track::eta) < configTracks.cfgCutEta && nabs(aod::track::pt) > configTracks.cMinPtcut) && + (nabs(aod::track::dcaXY) < configTracks.cMaxDCArToPVcut) && (nabs(aod::track::dcaZ) < configTracks.cMaxDCAzToPVcut); + + // Filter tofPIDFilter = aod::track::tofExpMom < 0.0f || ((aod::track::tofExpMom > 0.0f) && ( (nabs(aod::pidtof::tofNSigmaPi) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < configPID.pidnSigmaPreSelectionCut))); // TOF + // Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < configPID.pidnSigmaPreSelectionCut; // TPC + /* Filter trackFilter = (configTracks.trackSelection == AllTracks) || + ((configTracks.trackSelection == GlobalTracks) && requireGlobalTrackInFilter()) || + ((configTracks.trackSelection == GlobalTracksWoPtEta) && requireGlobalTrackWoPtEtaInFilter()) || + ((configTracks.trackSelection == GlobalTracksWoDCA) && requireGlobalTrackWoDCAInFilter()) || + ((configTracks.trackSelection == QualityTracks) && requireQualityTracksInFilter()) || + ((configTracks.trackSelection == InAcceptanceTracks) && requireTrackCutInFilter(TrackSelectionFlags::kInAcceptanceTracks)); + */ // Filter primarytrackFilter = requirePVContributor() && requirePrimaryTrack() && requireGlobalTrackWoDCA(); using EventCandidates = soa::Join; using TrackCandidates = soa::Filtered>; - using MCEventCandidates = soa::Join; using MCTrackCandidates = soa::Filtered>; @@ -290,20 +291,21 @@ struct Lambda1520analysisinpp { if (doprocessData) { // Track QA before cuts // --- Track - histos.add("QA/QAbefore/Track/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;{#sigma_{TOF}^{Kaon}};{#sigma_{TPC}^{Kaon}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPConly_Nsigma_ka", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;{#sigma_{TOF}^{Proton}};{#sigma_{TPC}^{Proton}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPConly_Nsigma_pr", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTH2F, {axisPt, axisDCAz}); - histos.add("QA/QAbefore/Track/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); - histos.add("QA/QAbefore/Track/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); - histos.add("QA/QAbefore/Track/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); - histos.add("QA/QAbefore/Track/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); - + if (cFillTrackQA) { + histos.add("QA/QAbefore/Track/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;{#sigma_{TOF}^{Kaon}};{#sigma_{TPC}^{Kaon}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPConly_Nsigma_ka", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;{#sigma_{TOF}^{Proton}};{#sigma_{TPC}^{Proton}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPConly_Nsigma_pr", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTH2F, {axisPt, axisDCAz}); + histos.add("QA/QAbefore/Track/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); + histos.add("QA/QAbefore/Track/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); + histos.add("QA/QAbefore/Track/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAbefore/Track/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + } if (cFillMultQA) { // Multiplicity correlation calibrations histos.add("MultCalib/centGloPVpr", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); @@ -400,8 +402,8 @@ struct Lambda1520analysisinpp { histos.add("QA/MC/h2GenEtaPt_afterRapcut", " #phi-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); histos.add("QA/MC/h2GenPhiRapidity_afterRapcut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); - histos.add("Result/MC/Genlambda1520pt", "pT distribution of True MC #Lambda(1520)0", kTHnSparseF, {axisMClabel, axisPt, axisMult}); - histos.add("Result/MC/Genantilambda1520pt", "pT distribution of True MC Anti-#Lambda(1520)0", kTHnSparseF, {axisMClabel, axisPt, axisMult}); + histos.add("Result/MC/Genlambda1520pt", "pT distribution of True MC #Lambda(1520)0", kTH3F, {axisMClabel, axisPt, axisMult}); + histos.add("Result/MC/Genantilambda1520pt", "pT distribution of True MC Anti-#Lambda(1520)0", kTH3F, {axisMClabel, axisPt, axisMult}); } if (doprocessMC) { histos.add("QA/MC/h2RecoEtaPt_after", " #eta-#it{p}_{T} distribution of Reconstructed #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPt}); @@ -474,16 +476,7 @@ struct Lambda1520analysisinpp { bool trackCut(const TrackType track) { // basic track cuts - if (std::abs(track.pt()) < configTracks.cMinPtcut) - return false; - if (configTracks.cDCAr7SigCut) { - if (std::abs(track.dcaXY()) > (0.004f + 0.013f / (track.pt()))) // 7 - Sigma cut - return false; - } else { - if (std::abs(track.dcaXY()) > configTracks.cMaxDCArToPVcut) - return false; - } - if (std::abs(track.dcaZ()) > configTracks.cMaxDCAzToPVcut) + if (configTracks.cDCAr7SigCut && std::abs(track.dcaXY()) > (0.004f + 0.013f / (track.pt()))) // 7 - Sigma cut return false; if (configTracks.cTPCNClsFound && (track.tpcNClsFound() < configTracks.cMinTPCNClsFound)) return false; @@ -499,10 +492,6 @@ struct Lambda1520analysisinpp { return false; if (configTracks.cfgGlobalTrack && !track.isGlobalTrack()) return false; - if (configTracks.cfgUseITSRefit && !track.passedITSRefit()) - return false; - if (configTracks.cfgUseTPCRefit && !track.passedTPCRefit()) - return false; return true; } @@ -734,28 +723,30 @@ struct Lambda1520analysisinpp { //// QA plots before the selection // --- Track QA all if constexpr (IsData) { - histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); - if (isTrk1hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); - histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); - } - if (!isTrk1hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_pr"), trk1ptPr, trk1NSigmaPrTPC); - } - histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); - if (isTrk2hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); - histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); - } - if (!isTrk2hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_ka"), trk2ptKa, trk2NSigmaKaTPC); - } + if (cFillTrackQA) { + histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); + histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); + } + if (!isTrk1hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_pr"), trk1ptPr, trk1NSigmaPrTPC); + } + histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); + histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); + } + if (!isTrk2hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_ka"), trk2ptKa, trk2NSigmaKaTPC); + } - histos.fill(HIST("QA/QAbefore/Track/dcaZ"), trk1ptPr, trk1.dcaZ()); - histos.fill(HIST("QA/QAbefore/Track/dcaXY"), trk1ptPr, trk1.dcaXY()); - histos.fill(HIST("QA/QAbefore/Track/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); - histos.fill(HIST("QA/QAbefore/Track/pT"), trk1ptPr); - histos.fill(HIST("QA/QAbefore/Track/eta"), trk1etaPr); + histos.fill(HIST("QA/QAbefore/Track/dcaZ"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/QAbefore/Track/dcaXY"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/QAbefore/Track/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAbefore/Track/pT"), trk1ptPr); + histos.fill(HIST("QA/QAbefore/Track/eta"), trk1etaPr); + } if (cFilldeltaEtaPhiPlots) { histos.fill(HIST("QAbefore/deltaEta"), deltaEta); histos.fill(HIST("QAbefore/deltaPhi"), deltaPhi); diff --git a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx index b1d5e088685..8afb4e0ab5a 100644 --- a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx @@ -101,8 +101,8 @@ struct phianalysisrun3_PbPb { Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; Configurable confRapidity{"confRapidity", 0.5, "Rapidity cut"}; - Configurable rapiditycut1{"rapiditycut1", -1.0f, "Rapidity cut lower"}; - Configurable rapiditycut2{"rapiditycut2", 1.0f, "Rapidity cut upper"}; + Configurable rapiditycut1{"rapiditycut1", -0.5f, "Rapidity cut lower"}; + Configurable rapiditycut2{"rapiditycut2", 0.5f, "Rapidity cut upper"}; Configurable timFrameEvsel{"timFrameEvsel", false, "TPC Time frame boundary cut"}; Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; @@ -112,6 +112,9 @@ struct phianalysisrun3_PbPb { Configurable confMaxRot{"confMaxRot", 7.0f * TMath::Pi() / 6.0f, "Maximum of rotation"}; Configurable pdgcheck{"pdgcheck", true, "pdgcheck"}; Configurable reco{"reco", true, "reco"}; + ConfigurableAxis ptAxiphi{"ptAxisphi", {200, 0.0f, 30.0f}, "phi pT axis"}; + ConfigurableAxis centAxiphi{"centAxisphi", {200, 0.0, 200.0}, "phi pT axis"}; + ConfigurableAxis massAxiphi{"massAxisphi", {200, 0.9, 1.1}, "phi pT axis"}; ConfigurableAxis binsImpactPar{"binsImpactPar", {VARIABLE_WIDTH, 0, 3.5, 5.67, 7.45, 8.85, 10.0, 11.21, 12.26, 13.28, 14.23, 15.27}, "Binning of the impact parameter axis"}; ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 10.0, 12.0}, "Binning of the pT axis"}; ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; @@ -128,68 +131,113 @@ struct phianalysisrun3_PbPb { AxisSpec impactParAxis = {binsImpactPar, "Impact Parameter"}; AxisSpec ptAxis = {binsPt, "#it{p}_{T} (GeV/#it{c})"}; AxisSpec centAxis = {binsCent, "V0M (%)"}; - histos.add("hCentrality", "Centrality distribution", kTH1F, {{200, 0.0, 200.0}}); - histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); - histos.add("hOccupancy", "Occupancy distribution", kTH1F, {{500, 0, 50000}}); - histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); if (!isMC) { - histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassRot", "Invariant mass of Phi meson Rotation", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassSame", "Invariant mass of Phi meson same", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h2PhiRapidity", "phi meson Rapidity", kTH2F, {{200, 0.0f, 20.0f}, {200, -4, 4}}); + histos.add("hCentrality", "Centrality distribution", kTH1F, {centAxiphi}); + histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); + histos.add("hOccupancy", "Occupancy distribution", kTH1F, {{500, 0, 50000}}); + histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); + histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h3PhiInvMassRot", "Invariant mass of Phi meson Rotation", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h3PhiInvMassSame", "Invariant mass of Phi meson same", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h2PhiRapidity", "phi meson Rapidity", kTH2F, {ptAxiphi, {200, -4, 4}}); + histos.add("hEta", "eta of kaon track candidates", HistType::kTH2F, {{200, -1.0f, 1.0f}, ptAxiphi}); + histos.add("hPhi", "phi of kaon track candidates", HistType::kTH2F, {{65, 0, 6.5}, ptAxiphi}); + + // DCA QA + // DCA histograms: separate for positive and negative kaons, range [-1.0, 1.0] + histos.add("QAbefore/trkDCAxy_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAxy_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAz_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAz_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + + histos.add("QAbefore/trkDCAxypt_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + histos.add("QAbefore/trkDCAxypt_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + histos.add("QAbefore/trkDCAzpt_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + histos.add("QAbefore/trkDCAzpt_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + + histos.add("QAafter/trkDCAxy_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAxy_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAz_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAz_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + + histos.add("QAafter/trkDCAxypt_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + histos.add("QAafter/trkDCAxypt_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + histos.add("QAafter/trkDCAzpt_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + histos.add("QAafter/trkDCAzpt_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, ptAxiphi}); + // PID QA before cuts + histos.add("QAbefore/TOF_TPC_Mapka_all_pos", "TOF + TPC Combined PID for positive Kaon;#sigma_{TOF}^{K^{+}};#sigma_{TPC}^{K^{+}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + histos.add("QAbefore/TOF_TPC_Mapka_all_neg", "TOF + TPC Combined PID for negative Kaon;#sigma_{TOF}^{K^{-}};#sigma_{TPC}^{K^{-}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + + histos.add("QAbefore/TOF_Nsigma_all_pos", "TOF NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("QAbefore/TOF_Nsigma_all_neg", "TOF NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + + histos.add("QAbefore/TPC_Nsigma_all_pos", "TPC NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("QAbefore/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + + // PID QA after cuts + histos.add("QAafter/TOF_TPC_Mapka_all_pos", "TOF + TPC Combined PID for positive Kaon;#sigma_{TOF}^{K^{+}};#sigma_{TPC}^{K^{+}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + histos.add("QAafter/TOF_TPC_Mapka_all_neg", "TOF + TPC Combined PID for negative Kaon;#sigma_{TOF}^{K^{-}};#sigma_{TPC}^{K^{-}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + + histos.add("QAafter/TOF_Nsigma_all_pos", "TOF NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("QAafter/TOF_Nsigma_all_neg", "TOF NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + + histos.add("QAafter/TPC_Nsigma_all_pos", "TPC NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("QAafter/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); } else if (isMC) { - histos.add("hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); + histos.add("hMC", "MC Event statistics", kTH1F, {{15, 0.0f, 15.0f}}); histos.add("EL1", "MC Event statistics", kTH1F, {impactParAxis}); histos.add("EL2", "MC Event statistics", kTH1F, {centAxis}); histos.add("ES1", "MC Event statistics", kTH1F, {impactParAxis}); histos.add("ES3", "MC Event statistics", kTH1F, {impactParAxis}); histos.add("ES2", "MC Event statistics", kTH1F, {centAxis}); histos.add("ES4", "MC Event statistics", kTH1F, {centAxis}); - histos.add("h1PhiGen", "Phi meson Gen", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("h1PhiGen1", "Phi meson Gen", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("Centrec", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); - histos.add("Centgen", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); + histos.add("h1PhiGen", "Phi meson Gen", kTH1F, {ptAxiphi}); + histos.add("h1PhiGen1", "Phi meson Gen", kTH1F, {ptAxiphi}); + histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {ptAxiphi}); + histos.add("Centrec", "MC Centrality", kTH1F, {centAxiphi}); + histos.add("Centgen", "MC Centrality", kTH1F, {centAxiphi}); histos.add("hVtxZgen", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); histos.add("hVtxZrec", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); - histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}}); - histos.add("h3PhiRec3", "Phi meson Rec", kTH3F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}, {200, 0.9, 1.1}}); - histos.add("h3Phi1Rec3", "Phi meson Rec", kTH3F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}, {200, 0.9, 1.1}}); - histos.add("h3PhiGen3", "Phi meson Gen", kTH3F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassMixedMC", "Invariant mass of Phi meson Mixed", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassSameMC", "Invariant mass of Phi meson same", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassRotMC", "Invariant mass of Phi meson Rotation", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}}); + histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {ptAxiphi, centAxiphi}); + histos.add("h3PhiRec3", "Phi meson Rec", kTH3F, {ptAxiphi, centAxiphi, massAxiphi}); + histos.add("h3Phi1Rec3", "Phi meson Rec", kTH3F, {ptAxiphi, centAxiphi, massAxiphi}); + histos.add("h3PhiGen3", "Phi meson Gen", kTH3F, {ptAxiphi, centAxiphi, massAxiphi}); + histos.add("h3PhiInvMassMixedMC", "Invariant mass of Phi meson Mixed", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h3PhiInvMassSameMC", "Invariant mass of Phi meson same", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h3PhiInvMassRotMC", "Invariant mass of Phi meson Rotation", kTH3F, {centAxiphi, ptAxiphi, massAxiphi}); + histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {ptAxiphi, centAxiphi}); histos.add("h2PhiGen1", "Phi meson gen", kTH2F, {ptAxis, impactParAxis}); - histos.add("h1PhiRec1", "Phi meson Rec", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("h1Phimassgen", "Phi meson gen", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h1Phimassrec", "Phi meson Rec", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h1Phimasssame", "Phi meson Rec", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h1Phimassmix", "Phi meson Rec", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h1Phimassrot", "Phi meson Rec", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h1Phi1massrec", "Phi meson Rec", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h1Phipt", "Phi meson Rec", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("h1PhiRec1", "Phi meson Rec", kTH1F, {ptAxiphi}); + histos.add("h1Phimassgen", "Phi meson gen", kTH1F, {massAxiphi}); + histos.add("h1Phimassrec", "Phi meson Rec", kTH1F, {massAxiphi}); + histos.add("h1Phimasssame", "Phi meson Rec", kTH1F, {massAxiphi}); + histos.add("h1Phimassmix", "Phi meson Rec", kTH1F, {massAxiphi}); + histos.add("h1Phimassrot", "Phi meson Rec", kTH1F, {massAxiphi}); + histos.add("h1Phi1massrec", "Phi meson Rec", kTH1F, {massAxiphi}); + histos.add("h1Phipt", "Phi meson Rec", kTH1F, {ptAxiphi}); histos.add("hOccupancy1", "Occupancy distribution", kTH1F, {{500, 0, 50000}}); - histos.add("h1PhifinalRec", "Phi meson Rec", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("h1Phifinalgenmass", "Phi meson gen mass", kTH1F, {{200, 0.9, 1.1}}); - histos.add("h3PhifinalRec", "Phi meson Rec", kTH3F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}, {200, 0.9, 1.1}}); - histos.add("h1PhifinalGen", "Phi meson Gen", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("h2PhifinalGen", "Phi meson Gen", kTH2F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}}); + histos.add("h1PhifinalRec", "Phi meson Rec", kTH1F, {ptAxiphi}); + histos.add("h1Phifinalgenmass", "Phi meson gen mass", kTH1F, {massAxiphi}); + histos.add("h3PhifinalRec", "Phi meson Rec", kTH3F, {ptAxiphi, centAxiphi, massAxiphi}); + histos.add("h1PhifinalGen", "Phi meson Gen", kTH1F, {ptAxiphi}); + histos.add("h2PhifinalGen", "Phi meson Gen", kTH2F, {ptAxiphi, centAxiphi}); histos.add("hMC1", "MC Event statistics", kTH1F, {{15, 0.0f, 15.0f}}); - histos.add("Centrec1", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); - histos.add("Centgen1", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); - histos.add("h1PhiRecsplit1", "Phi meson Rec split", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("Centrec1", "MC Centrality", kTH1F, {centAxiphi}); + histos.add("Centsame", "MC Centrality", kTH1F, {centAxiphi}); + histos.add("Centmix", "MC Centrality", kTH1F, {centAxiphi}); + histos.add("Centgen1", "MC Centrality", kTH1F, {centAxiphi}); + histos.add("h1PhiRecsplit1", "Phi meson Rec split", kTH1F, {ptAxiphi}); histos.add("hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("hImpactParameterRec", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("hImpactParameterGenCen", "Impact parameter of generated MC events", kTH2F, {impactParAxis, centAxis}); histos.add("hImpactParameterRecCen", "Impact parameter of generated MC events", kTH2F, {impactParAxis, centAxis}); - histos.add("TOF_Nsigma_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("TPC_Nsigma_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("TOF_Nsigma1_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("TPC_Nsigma1_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("trkDCAxy", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("trkDCAz", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("TOF_Nsigma_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("TPC_Nsigma_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("TOF_Nsigma1_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("TPC_Nsigma1_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxiphi, ptAxiphi}}); + histos.add("trkDCAxy", "DCAxy distribution of positive kaon track candidates", HistType::kTH3F, {{150, -1.0f, 1.0f}, centAxiphi, ptAxiphi}); + histos.add("trkDCAz", "DCAxy distribution of negative kaon track candidates", HistType::kTH3F, {{150, -1.0f, 1.0f}, centAxiphi, ptAxiphi}); if (doprocessEvtLossSigLossMC) { histos.add("QAevent/hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("QAevent/hImpactParameterRec", "Impact parameter of selected MC events", kTH1F, {impactParAxis}); @@ -198,50 +246,6 @@ struct phianalysisrun3_PbPb { histos.add("QAevent/phigenAfterEvtSel", "phi after event selections", kTH2F, {ptAxis, impactParAxis}); } } - - histos.add("hEta", "eta of kaon track candidates", HistType::kTH2F, {{200, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("hPhi", "phi of kaon track candidates", HistType::kTH2F, {{65, 0, 6.5}, {200, 0.0f, 20.0f}}); - - // DCA QA - // DCA histograms: separate for positive and negative kaons, range [-1.0, 1.0] - histos.add("QAbefore/trkDCAxy_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("QAbefore/trkDCAxy_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("QAbefore/trkDCAz_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("QAbefore/trkDCAz_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - - histos.add("QAbefore/trkDCAxypt_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("QAbefore/trkDCAxypt_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("QAbefore/trkDCAzpt_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("QAbefore/trkDCAzpt_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - - histos.add("QAafter/trkDCAxy_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("QAafter/trkDCAxy_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("QAafter/trkDCAz_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - histos.add("QAafter/trkDCAz_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); - - histos.add("QAafter/trkDCAxypt_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("QAafter/trkDCAxypt_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("QAafter/trkDCAzpt_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - histos.add("QAafter/trkDCAzpt_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH2F, {{150, -1.0f, 1.0f}, {200, 0.0f, 20.0f}}); - // PID QA before cuts - histos.add("QAbefore/TOF_TPC_Mapka_all_pos", "TOF + TPC Combined PID for positive Kaon;#sigma_{TOF}^{K^{+}};#sigma_{TPC}^{K^{+}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); - histos.add("QAbefore/TOF_TPC_Mapka_all_neg", "TOF + TPC Combined PID for negative Kaon;#sigma_{TOF}^{K^{-}};#sigma_{TPC}^{K^{-}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); - - histos.add("QAbefore/TOF_Nsigma_all_pos", "TOF NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("QAbefore/TOF_Nsigma_all_neg", "TOF NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - - histos.add("QAbefore/TPC_Nsigma_all_pos", "TPC NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("QAbefore/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - - // PID QA after cuts - histos.add("QAafter/TOF_TPC_Mapka_all_pos", "TOF + TPC Combined PID for positive Kaon;#sigma_{TOF}^{K^{+}};#sigma_{TPC}^{K^{+}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); - histos.add("QAafter/TOF_TPC_Mapka_all_neg", "TOF + TPC Combined PID for negative Kaon;#sigma_{TOF}^{K^{-}};#sigma_{TPC}^{K^{-}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); - - histos.add("QAafter/TOF_Nsigma_all_pos", "TOF NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("QAafter/TOF_Nsigma_all_neg", "TOF NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - - histos.add("QAafter/TPC_Nsigma_all_pos", "TPC NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("QAafter/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); } double massKa = o2::constants::physics::MassKPlus; @@ -387,7 +391,7 @@ struct phianalysisrun3_PbPb { aod::McTrackLabels>>; using CollisionMCTrueTable = aod::McCollisions; using TrackMCTrueTable = aod::McParticles; - using CollisionMCRecTableCentFT0C = soa::SmallGroups>; + using CollisionMCRecTableCentFT0C = soa::SmallGroups>; using TrackMCRecTable = soa::Join; using FilTrackMCRecTable = soa::Filtered; @@ -919,33 +923,61 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("hMC"), 2); return; } - for (const auto& RecCollision : RecCollisions) { + for (auto& RecCollision : RecCollisions) { histos.fill(HIST("hMC"), 3); - if (!RecCollision.sel8()) { - histos.fill(HIST("hMC"), 4); + if (!RecCollision.sel8() || std::abs(RecCollision.posZ()) > cfgCutVertex) { continue; } - if (timFrameEvsel && (!RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - histos.fill(HIST("hMC"), 5); + histos.fill(HIST("hMC"), 4); + if (additionalEvSel1 && !RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { continue; } - if (additionalEvSel2 && (!RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup) || !RecCollision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + histos.fill(HIST("hMC"), 5); + if (additionalEvSel2 && !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { continue; } + histos.fill(HIST("hMC"), 6); + if (additionalEvSel3 && !RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + continue; + } + histos.fill(HIST("hMC"), 7); + if (additionalEvSel4 && !RecCollision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + histos.fill(HIST("hMC"), 8); + if (additionalEvSel5 && !RecCollision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + histos.fill(HIST("hMC"), 9); + if (additionalEvSel6 && !RecCollision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + continue; + } + histos.fill(HIST("hMC"), 10); int occupancy = RecCollision.trackOccupancyInTimeRange(); if (fillOccupancy && (occupancy > cfgCutOccupancy)) { continue; } - if (std::abs(RecCollision.posZ()) > cfgCutVertex) { - histos.fill(HIST("hMC"), 6); - continue; + histos.fill(HIST("hMC"), 11); + const int kCentFT0C = 0; + const int kCentFT0A = 1; + const int kCentFT0M = 2; + const int kCentFV0A = 3; + auto centrality = -1.0; + if (centestimator == kCentFT0C) { + centrality = RecCollision.centFT0C(); + } else if (centestimator == kCentFT0A) { + centrality = RecCollision.centFT0A(); + } else if (centestimator == kCentFT0M) { + centrality = RecCollision.centFT0M(); + } else if (centestimator == kCentFV0A) { + centrality = RecCollision.centFV0A(); } - histos.fill(HIST("hMC"), 7); - auto centrality = RecCollision.centFT0C(); + auto oldindex = -999; auto rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); // loop over reconstructed particle - for (const auto& track1 : rectrackspart) { + int ntrack1 = 0; + for (auto& track1 : rectrackspart) { if (!selectionTrack(track1)) { continue; } @@ -959,7 +991,8 @@ struct phianalysisrun3_PbPb { continue; } auto track1ID = track1.index(); - for (const auto& track2 : rectrackspart) { + ntrack1 = ntrack1 + 1; + for (auto& track2 : rectrackspart) { auto track2ID = track2.index(); if (track2ID <= track1ID) { continue; @@ -1003,27 +1036,16 @@ struct phianalysisrun3_PbPb { if (mothertrack1 != mothertrack2) { continue; } - if (std::abs(mothertrack1.y()) > confRapidity) { - continue; - } if (pdgcheck && std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kPhi) { continue; } - if (!ispTdepPID && (!selectionPID(track1) || !selectionPID(track2))) { - continue; - } - if (ispTdepPID && (!selectionPIDpTdependent(track1) || !selectionPIDpTdependent(track2))) { - continue; - } if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { histos.fill(HIST("h1PhiRecsplit"), mothertrack1.pt()); continue; } oldindex = mothertrack1.globalIndex(); - if (track1.sign() * track2.sign() < 0) { - kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); - } + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); phiMesonMother = kaonPlus + kaonMinus; if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { @@ -1034,6 +1056,7 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("h1Phimassrec"), phiMesonMother.M()); histos.fill(HIST("h3PhiRec3"), phiMesonMother.pt(), centrality, phiMesonMother.M()); histos.fill(HIST("Centrec"), centrality); + histos.fill(HIST("hVtxZrec"), RecCollision.posZ()); } } } @@ -1324,6 +1347,7 @@ struct phianalysisrun3_PbPb { } float multiplicity{-1}; multiplicity = collision.centFT0C(); + histos.fill(HIST("Centsame"), multiplicity); for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { continue; @@ -1422,6 +1446,7 @@ struct phianalysisrun3_PbPb { continue; } auto multiplicity = c1.centFT0C(); + histos.fill(HIST("Centmix"), multiplicity); for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { histos.fill(HIST("hMC"), 6.5); if (!selectionTrack(t1)) { @@ -1667,8 +1692,8 @@ struct phianalysisrun3_PbPb { } histos.fill(HIST("TPC_Nsigma1_MC"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); histos.fill(HIST("TOF_Nsigma1_MC"), track1.tofNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("trkDCAxy"), track1.dcaXY()); - histos.fill(HIST("trkDCAz"), track1.dcaZ()); + histos.fill(HIST("trkDCAxy"), track1.dcaXY(), multiplicity, track1.pt()); + histos.fill(HIST("trkDCAz"), track1.dcaZ(), multiplicity, track1.pt()); if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { histos.fill(HIST("h1PhiRecsplit1"), mothertrack1.pt()); continue; diff --git a/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx b/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx index 4ea692e246e..40d04a9986b 100644 --- a/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx +++ b/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx @@ -64,6 +64,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; +using namespace o2::aod::rctsel; struct phispectrapbpbqa { double bz = 0.; @@ -75,6 +76,13 @@ struct phispectrapbpbqa { Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; } cfgCcdbParam; + + struct : ConfigurableGroup { + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + } rctCut; + TH3D* hTPCCallib; TH3D* hTOFCallib; @@ -82,6 +90,8 @@ struct phispectrapbpbqa { Configurable ConfPathTOF{"ConfPathTOF", "Users/s/skundu/My/Object/PIDcallib/TOF", "Weight path TOF"}; // events + Configurable applyStrictEvSel{"applyStrictEvSel", true, "Apply strict event selection"}; + Configurable applyMCsel8{"applyMCsel8", false, "Apply sel8 in MC"}; Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 10, "Number of event mixing"}; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; // ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {8, 0, 80}, "multiplicity percentile for bin"}; @@ -96,10 +106,12 @@ struct phispectrapbpbqa { Configurable cfgITScluster{"cfgITScluster", 4, "Number of ITS cluster"}; Configurable cfgTPCcluster{"cfgTPCcluster", 80, "Number of TPC cluster"}; + Configurable cfgTPCPIDcluster{"cfgTPCPIDcluster", 80, "Number of TPC PID cluster"}; Configurable cfgTPCcrossedRows{"cfgTPCcrossedRows", 90, "Number of TPC crossed Rows"}; Configurable cfgUpdatePID{"cfgUpdatePID", false, "Update PID callibration"}; Configurable applyPID{"applyPID", true, "Apply PID"}; + Configurable applyPIDCluster{"applyPIDCluster", true, "Apply PID cluster"}; Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; Configurable timeFrameMC{"timeFrameMC", false, "time frame cut in MC"}; @@ -107,7 +119,7 @@ struct phispectrapbpbqa { Configurable ispTdepPID{"ispTdepPID", false, "pT dependent PID"}; Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.5, "cut TOF beta"}; Configurable nsigmaCutTPC{"nsigmacutTPC", 2.0, "Value of the TPC Nsigma cut"}; - Configurable nsigmaCutCombined{"nsigmaCutCombined", 2.0, "Value of the Combined TPC-TOF Nsigma cut"}; + Configurable applyTOF{"applyTOF", true, "Apply TOF"}; ConfigurableAxis axisOccupancy{"axisOccupancy", {VARIABLE_WIDTH, -1.0, 200.0, 500.0, 1000.0, 2000.0f, 4000.0, 10000.0f, 100000.0f}, "occupancy axis"}; struct : ConfigurableGroup { ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {90, 0.98, 1.07}, "#it{M} (GeV/#it{c}^{2})"}; @@ -122,7 +134,7 @@ struct phispectrapbpbqa { Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter centralityFilter = nabs(aod::cent::centFT0C) < cfgCutCentrality; Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); - // Filter PIDcutFilter = nabs(aod::pidtpc::tpcNSigmaKa) < nsigmaCutTPC; + Filter PIDcutFilter = nabs(aod::pidtpc::tpcNSigmaKa) < nsigmaCutTPC; // Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using EventCandidates = soa::Filtered>; @@ -141,13 +153,13 @@ struct phispectrapbpbqa { Partition negTracks = aod::track::signed1Pt < cfgCutCharge; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - + RCTFlagsChecker rctChecker; // Event selection cuts - Alex // TF1* fMultPVCutLow = nullptr; void init(o2::framework::InitContext&) { - + rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); histos.add("hphiSE", "hphiSE", HistType::kTHnSparseF, {cnfgaxis.configThnAxisInvMass, cnfgaxis.configThnAxisPt, cnfgaxis.configThnAxisCentrality, axisOccupancy, cnfgaxis.configThnAxisSector}, true); histos.add("hphiME", "hphiME", HistType::kTHnSparseF, {cnfgaxis.configThnAxisInvMass, cnfgaxis.configThnAxisPt, cnfgaxis.configThnAxisCentrality, axisOccupancy, cnfgaxis.configThnAxisSector}, true); histos.add("hphiGen", "hphiGen", HistType::kTHnSparseF, {cnfgaxis.configThnAxisInvMass, cnfgaxis.configThnAxisPt, cnfgaxis.configThnAxisCentrality, axisOccupancy}, true); @@ -157,6 +169,8 @@ struct phispectrapbpbqa { histos.add("hPhiMommentum", "hPhiMommentum", kTH3F, {{36, 0, 6.283}, {200, -10.0, 10.0}, axisOccupancy}); + histos.add("hNsigmaTPCBeforeCut", "NsigmaKaon TPC Before Cut", kTH3F, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy}); + histos.add("hNsigmaTOFBeforeCut", "NsigmaKaon TOF Before Cut", kTH3F, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy}); histos.add("hNsigmaTPCAfterCut", "NsigmaKaon TPC After Cut", kTH3F, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy}); histos.add("hNsigmaTOFAfterCut", "NsigmaKaon TOF After Cut", kTH3F, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy}); @@ -170,7 +184,7 @@ struct phispectrapbpbqa { histos.add("hOccupancy", "hOccupancy", kTH2F, {axisOccupancy, cnfgaxis.configThnAxisCentrality}); histos.add("hMC", "hMC", kTH1F, {{20, 0.0f, 20.0f}}); histos.add("h1PhiRecsplit", "h1PhiRecsplit", kTH1F, {{100, 0.0f, 10.0f}}); - + histos.add("hData", "hData", kTH1F, {{20, 0.0f, 20.0f}}); ccdb->setURL(cfgCcdbParam.cfgURL); ccdbApi.init("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); @@ -205,6 +219,9 @@ struct phispectrapbpbqa { if (!(candidate.isGlobalTrack() && candidate.isPVContributor() && candidate.itsNCls() > cfgITScluster && candidate.tpcNClsFound() > cfgTPCcluster && candidate.tpcNClsCrossedRows() > cfgTPCcrossedRows)) { return false; } + if (applyPIDCluster && candidate.tpcNClsPID() < cfgTPCPIDcluster) { + return false; + } return true; } @@ -214,8 +231,28 @@ struct phispectrapbpbqa { if (candidate.p() < 0.7 && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { return true; } - if (candidate.p() >= 0.7 && candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Sqrt(nsigmaTPC * nsigmaTPC + nsigmaTOF * nsigmaTOF) < nsigmaCutCombined) { - return true; + if (candidate.p() > 0.7 && candidate.hasTOF() && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + if (candidate.p() > 0.7 && candidate.p() < 1.6 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -5.0 && nsigmaTOF < 10.0) { + return true; + } + if (candidate.p() >= 1.6 && candidate.p() < 2.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -3.0 && nsigmaTOF < 10.0) { + return true; + } + if (candidate.p() >= 2.0 && candidate.p() < 2.5 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -3.0 && nsigmaTOF < 6.0) { + return true; + } + if (candidate.p() >= 2.5 && candidate.p() < 4.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -2.5 && nsigmaTOF < 4.0) { + return true; + } + if (candidate.p() >= 4.0 && candidate.p() < 5.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -4.0 && nsigmaTOF < 3.0) { + return true; + } + if (candidate.p() >= 5.0 && candidate.p() < 6.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -4.0 && nsigmaTOF < 2.5) { + return true; + } + if (candidate.p() >= 6.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -3.0 && nsigmaTOF < 3.0) { + return true; + } } return false; } @@ -223,13 +260,34 @@ struct phispectrapbpbqa { template bool selectionPID(const T& candidate, double nsigmaTPC, double nsigmaTOF) { - if (candidate.p() < 0.7 && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { - return true; - } - if (candidate.p() >= 0.7 && candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Sqrt(nsigmaTPC * nsigmaTPC + nsigmaTOF * nsigmaTOF) < nsigmaCutCombined) { - return true; - } - if (candidate.p() >= 0.7 && !candidate.hasTOF() && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + if (applyTOF) { + if (!candidate.hasTOF() && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + return true; + } + if (candidate.p() > 0.5 && candidate.hasTOF() && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + if (candidate.p() > 0.5 && candidate.p() < 1.6 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -5.0 && nsigmaTOF < 10.0) { + return true; + } + if (candidate.p() >= 1.6 && candidate.p() < 2.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -3.0 && nsigmaTOF < 10.0) { + return true; + } + if (candidate.p() >= 2.0 && candidate.p() < 2.5 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -3.0 && nsigmaTOF < 6.0) { + return true; + } + if (candidate.p() >= 2.5 && candidate.p() < 4.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -2.5 && nsigmaTOF < 4.0) { + return true; + } + if (candidate.p() >= 4.0 && candidate.p() < 5.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -4.0 && nsigmaTOF < 3.0) { + return true; + } + if (candidate.p() >= 5.0 && candidate.p() < 6.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -4.0 && nsigmaTOF < 2.5) { + return true; + } + if (candidate.p() >= 6.0 && candidate.beta() > cfgCutTOFBeta && nsigmaTOF > -3.0 && nsigmaTOF < 3.0) { + return true; + } + } + } else if (TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { return true; } return false; @@ -279,19 +337,34 @@ struct phispectrapbpbqa { int lastRunNumber = -999; void processSameEvent(EventCandidates::iterator const& collision, TrackCandidates const&, aod::BCsWithTimestamps const&) { - if (!collision.sel8() || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + histos.fill(HIST("hData"), 1); + if (!collision.sel8() || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + histos.fill(HIST("hData"), 2); + if (rctCut.requireRCTFlagChecker) { + if (!rctChecker(collision)) { + return; + } + } + histos.fill(HIST("hData"), 3); + if (applyStrictEvSel && (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll) || !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow))) { return; } + histos.fill(HIST("hData"), 4); auto centrality = collision.centFT0C(); int occupancy = collision.trackOccupancyInTimeRange(); histos.fill(HIST("hCentrality"), centrality); histos.fill(HIST("hVtxZ"), collision.posZ()); - auto bc = collision.template bc_as(); + + /*auto bc = collision.template bc_as(); currentRunNumber = collision.bc_as().runNumber(); if (currentRunNumber != lastRunNumber) { bz = getMagneticField(bc.timestamp()); } lastRunNumber = currentRunNumber; + */ + auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -324,6 +397,8 @@ struct phispectrapbpbqa { if (track1.hasTOF()) { histos.fill(HIST("hNsigmaTOF"), nSigmaTOF, track1.p(), occupancy, centrality); } + histos.fill(HIST("hNsigmaTPCBeforeCut"), nSigmaTPC, track1.p(), occupancy); + histos.fill(HIST("hNsigmaTOFBeforeCut"), nSigmaTOF, track1.p(), occupancy); if (applyPID) { if (ispTdepPID && !selectionPIDpTdependent(track1, nSigmaTPC, nSigmaTOF)) { continue; @@ -374,6 +449,8 @@ struct phispectrapbpbqa { if (track2.hasTOF()) { histos.fill(HIST("hNsigmaTOF"), nSigmaTOF2, track2.p(), occupancy, centrality); } + histos.fill(HIST("hNsigmaTPCBeforeCut"), nSigmaTPC2, track2.p(), occupancy); + histos.fill(HIST("hNsigmaTOFBeforeCut"), nSigmaTOF2, track2.p(), occupancy); } if (applyPID) { if (ispTdepPID && !selectionPIDpTdependent(track2, nSigmaTPC2, nSigmaTOF2)) { @@ -428,12 +505,23 @@ struct phispectrapbpbqa { BinningTypeVertexContributor binningOnPositions{{axisVertex, cnfgaxis.configThnAxisCentrality, axisOccupancy}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; for (auto& [collision1, tracks1, collision2, tracks2] : pair) { - if (!collision1.sel8() || !collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (!collision1.sel8() || !collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (!collision2.sel8() || !collision2.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision2.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (!collision2.sel8() || !collision2.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision2.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } + if (rctCut.requireRCTFlagChecker) { + if (!rctChecker(collision1) || !rctChecker(collision2)) { + continue; + } + } + if (applyStrictEvSel && (!collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll) || !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow))) { + return; + } + if (applyStrictEvSel && (!collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll) || !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow))) { + return; + } int occupancy = collision1.trackOccupancyInTimeRange(); auto centrality = collision1.centFT0C(); for (auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { @@ -519,11 +607,15 @@ struct phispectrapbpbqa { return; } for (auto& RecCollision : RecCollisions) { - if (!RecCollision.sel8()) { + if (applyMCsel8 && !RecCollision.sel8()) { histos.fill(HIST("hMC"), 3); continue; } - if (!RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup) || !RecCollision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !RecCollision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !RecCollision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (!applyMCsel8 && !RecCollision.selection_bit(aod::evsel::kIsTriggerTVX)) { + histos.fill(HIST("hMC"), 3); + continue; + } + if (!RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup) || !RecCollision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !RecCollision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { histos.fill(HIST("hMC"), 4); continue; } @@ -536,12 +628,21 @@ struct phispectrapbpbqa { histos.fill(HIST("hMC"), 7); continue; } - if (readOutFrameMC && RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + if (readOutFrameMC && !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { histos.fill(HIST("hMC"), 8); continue; } - histos.fill(HIST("hMC"), 9); + if (rctCut.requireRCTFlagChecker) { + if (!rctChecker(RecCollision)) { + continue; + } + } + histos.fill(HIST("hMC"), 10); + if (applyStrictEvSel && (!RecCollision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll) || !RecCollision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow))) { + return; + } + histos.fill(HIST("hMC"), 11); auto centrality = RecCollision.centFT0C(); int occupancy = RecCollision.trackOccupancyInTimeRange(); histos.fill(HIST("hOccupancy"), occupancy, centrality); @@ -549,6 +650,7 @@ struct phispectrapbpbqa { auto oldindex = -999; auto Rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); // loop over reconstructed particle + int ntrack1 = 0; for (auto track1 : Rectrackspart) { if (!selectionTrack(track1)) { continue; @@ -557,6 +659,32 @@ struct phispectrapbpbqa { continue; } auto track1ID = track1.index(); + // PID track 1 + double nSigmaTPC = track1.tpcNSigmaKa(); + double nSigmaTOF = track1.tofNSigmaKa(); + if (!track1.hasTOF()) { + nSigmaTOF = -9999.99; + } + if (cfgUpdatePID) { + nSigmaTPC = (nSigmaTPC - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track1.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track1.p(), centrality, occupancy)); + if (track1.hasTOF()) { + nSigmaTOF = (nSigmaTOF - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track1.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track1.p(), centrality, occupancy)); + } + } + histos.fill(HIST("hNsigmaTPCBeforeCut"), nSigmaTPC, track1.p(), occupancy); + histos.fill(HIST("hNsigmaTOFBeforeCut"), nSigmaTOF, track1.p(), occupancy); + + if (applyPID) { + if (ispTdepPID && !selectionPIDpTdependent(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + if (!ispTdepPID && !selectionPID(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + histos.fill(HIST("hNsigmaTPCAfterCut"), nSigmaTPC, track1.p(), occupancy); + histos.fill(HIST("hNsigmaTOFAfterCut"), nSigmaTOF, track1.p(), occupancy); + } + ntrack1 = ntrack1 + 1; for (auto track2 : Rectrackspart) { auto track2ID = track2.index(); if (track2ID <= track1ID) { @@ -574,18 +702,7 @@ struct phispectrapbpbqa { if (track1.sign() * track2.sign() > 0) { continue; } - // PID track 1 - double nSigmaTPC = track1.tpcNSigmaKa(); - double nSigmaTOF = track1.tofNSigmaKa(); - if (!track1.hasTOF()) { - nSigmaTOF = -9999.99; - } - if (cfgUpdatePID) { - nSigmaTPC = (nSigmaTPC - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track1.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track1.p(), centrality, occupancy)); - if (track1.hasTOF()) { - nSigmaTOF = (nSigmaTOF - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track1.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track1.p(), centrality, occupancy)); - } - } + // PID track 2 double nSigmaTPC2 = track2.tpcNSigmaKa(); double nSigmaTOF2 = track2.tofNSigmaKa(); @@ -598,14 +715,11 @@ struct phispectrapbpbqa { nSigmaTOF2 = (nSigmaTOF2 - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track2.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track2.p(), centrality, occupancy)); } } + if (ntrack1 == 1) { + histos.fill(HIST("hNsigmaTPCBeforeCut"), nSigmaTPC2, track2.p(), occupancy); + histos.fill(HIST("hNsigmaTOFBeforeCut"), nSigmaTOF2, track2.p(), occupancy); + } if (applyPID) { - if (ispTdepPID && !selectionPIDpTdependent(track1, nSigmaTPC, nSigmaTOF)) { - continue; - } - if (!ispTdepPID && !selectionPID(track1, nSigmaTPC, nSigmaTOF)) { - continue; - } - if (ispTdepPID && !selectionPIDpTdependent(track2, nSigmaTPC2, nSigmaTOF2)) { continue; } @@ -613,6 +727,10 @@ struct phispectrapbpbqa { continue; } } + if (ntrack1 == 1) { + histos.fill(HIST("hNsigmaTPCAfterCut"), nSigmaTPC2, track2.p(), occupancy); + histos.fill(HIST("hNsigmaTOFAfterCut"), nSigmaTOF2, track2.p(), occupancy); + } const auto mctrack1 = track1.mcParticle(); const auto mctrack2 = track2.mcParticle(); diff --git a/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx b/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx index 07ed10a9460..d33b0e589cf 100644 --- a/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx +++ b/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx @@ -1058,13 +1058,15 @@ struct Xi1530Analysisqa { aod::ResoTracks const& resoTracks, aod::ResoCascades const& cascTracks) { - auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); - auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + if (cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision + auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision - if (cRecoINELgt0 && !coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision - return; + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + } histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); auto multiplicity = resoCollision.cent(); @@ -1073,52 +1075,92 @@ struct Xi1530Analysisqa { // Reconstructed level MC for the track void processMC(ResoMCCols::iterator const& resoCollision, - aod::ResoCollisionColls const& resoCollisionIndex, + aod::ResoCollisionColls const& collisionIndex, soa::Join const& collisionsMC, soa::Join const& cascTracks, soa::Join const& resoTracks, soa::Join const&) { - if (!resoCollision.isInAfterAllCuts() || (std::abs(resoCollision.posZ()) > cZvertCutMC)) // MC event selection, all cuts missing vtx cut - return; + float multiplicity; + if (cMCCent && cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - auto linkRow = resoCollisionIndex.iteratorAt(resoCollision.globalIndex()); - const int collId = linkRow.collisionId(); + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision - auto coll = collisionsMC.iteratorAt(collId); + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; - if (cRecoINELgt0 && !coll.isInelGt0()) - return; + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else if (!cMCCent && cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision - auto mcColl = coll.mcCollision_as>(); + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; - auto multiplicityReco = resoCollision.cent(); // Reco level multiplicity per. - auto multiplicityGen = mcColl.centFT0M(); // Gen level multiplicity per. + multiplicity = resoCollision.cent(); + } else if (cMCCent && !cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - float multiplicity = cMCCent ? multiplicityGen : multiplicityReco; + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else { + multiplicity = resoCollision.cent(); + } + + if (!resoCollision.isInAfterAllCuts() || (std::abs(resoCollision.posZ()) > cZvertCutMC)) // MC event selection, all cuts missing vtx cut + return; fillHistograms(resoCollision, multiplicity, resoTracks, cascTracks); } // Truth level MC for the track with reco event void processMCTrue(ResoMCCols::iterator const& resoCollision, - aod::ResoCollisionColls const& resoCollisionIndex, + aod::ResoCollisionColls const& collisionIndex, aod::ResoMCParents const& resoParents, aod::ResoCollisionCandidatesMC const& collisionsMC, soa::Join const&) { + float multiplicity; + if (cMCCent && cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - auto linkRow = resoCollisionIndex.iteratorAt(resoCollision.globalIndex()); - const int collId = linkRow.collisionId(); + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision - auto coll = collisionsMC.iteratorAt(collId); + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; - auto mcColl = coll.mcCollision_as>(); + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else if (!cMCCent && cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - auto multiplicityReco = resoCollision.cent(); // Reco level multiplicity per. - auto multiplicityGen = mcColl.centFT0M(); // Gen level multiplicity per. + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision - float multiplicity = cMCCent ? multiplicityGen : multiplicityReco; + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + + multiplicity = resoCollision.cent(); + } else if (cMCCent && !cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisionsMC.iteratorAt(collId); // Take original collision matched with resoCollision + + auto mcColl = coll.mcCollision_as>(); + multiplicity = mcColl.centFT0M(); + } else { + multiplicity = resoCollision.cent(); + } for (const auto& part : resoParents) { // loop over all pre-filtered MC particles if (std::abs(part.pdgCode()) != kXiStar || std::abs(part.y()) >= cfgRapidityCut) @@ -1171,13 +1213,15 @@ struct Xi1530Analysisqa { aod::ResoMicroTracks const& resomicrotracks, aod::ResoCascades const& cascTracks) { - auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); - auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + if (cRecoINELgt0) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision + auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision - if (cRecoINELgt0 && !coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision - return; + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; + } histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); auto multiplicity = resoCollision.cent(); @@ -1222,15 +1266,16 @@ struct Xi1530Analysisqa { for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { - const auto rcIdx = collision1.globalIndex(); - - const auto linkRow = collisionIndex.iteratorAt(rcIdx); - const auto collId = linkRow.collisionId(); + if (cRecoINELgt0) { + const auto rcIdx = collision1.globalIndex(); + auto linkRow = collisionIndex.iteratorAt(rcIdx); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision - auto coll = collisions.iteratorAt(collId); - if (cRecoINELgt0 && !coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision - continue; + auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision + if (!coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + continue; + } histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); auto multiplicity = collision1.cent(); fillHistograms(collision1, multiplicity, tracks1, tracks2); diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt index 100b8667aab..db4a211e4fa 100644 --- a/PWGLF/Tasks/Strangeness/CMakeLists.txt +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -133,7 +133,7 @@ o2physics_add_dpl_workflow(lambdak0sflattenicity o2physics_add_dpl_workflow(lambdalambda SOURCES lambdalambda.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(lambdajetpolarization diff --git a/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx b/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx index 43e10b719b8..a4b321f8d82 100644 --- a/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx @@ -130,6 +130,8 @@ struct lambdaTwoPartPolarization { ConfigurableAxis cosSigAxis{"cosSigAxis", {110, -1.05, 1.05}, "Signal cosine axis"}; ConfigurableAxis cosAccAxis{"cosAccAxis", {110, -7.05, 7.05}, "Accepatance cosine axis"}; + ConfigurableAxis vertexAxis{"vertexAxis", {5, -10, 10}, "vertex axis for mixing"}; + TF1* fMultPVCutLow = nullptr; TF1* fMultPVCutHigh = nullptr; @@ -402,7 +404,68 @@ struct lambdaTwoPartPolarization { FillHistograms(collision, collision, V0s, V0s); } - PROCESS_SWITCH(lambdaTwoPartPolarization, processDataSame, "Process Event for same data", true); + PROCESS_SWITCH(lambdaTwoPartPolarization, processDataSame, "Process event for same data", true); + + SliceCache cache; + Preslice tracksPerCollisionV0 = aod::v0data::collisionId; + + using BinningTypeT0C = ColumnBinningPolicy; + BinningTypeT0C colBinningT0C{{vertexAxis, centAxis}, true}; + + void processDataMixedT0C(EventCandidates const& collisions, + TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + { + for (auto& [c1, c2] : selfCombinations(colBinningT0C, cfgNoMixedEvents, -1, collisions, collisions)) { + + if (c1.index() == c2.index()) + continue; + + centrality = c1.centFT0C(); + if (cfgAccCor) { + auto bc = c1.bc_as(); + AccMap = ccdb->getForTimeStamp(cfgAccCorPath.value, bc.timestamp()); + } + if (!eventSelected(c1)) + continue; + if (!eventSelected(c2)) + continue; + + auto tracks1 = V0s.sliceBy(tracksPerCollisionV0, c1.globalIndex()); + auto tracks2 = V0s.sliceBy(tracksPerCollisionV0, c2.globalIndex()); + + FillHistograms(c1, c2, tracks1, tracks2); + } + } + PROCESS_SWITCH(lambdaTwoPartPolarization, processDataMixedT0C, "Process event for mixed data in PbPb", false); + + using BinningTypeT0M = ColumnBinningPolicy; + BinningTypeT0M colBinningT0M{{vertexAxis, centAxis}, true}; + + void processDataMixedT0M(EventCandidates const& collisions, + TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + { + for (auto& [c1, c2] : selfCombinations(colBinningT0M, cfgNoMixedEvents, -1, collisions, collisions)) { + + if (c1.index() == c2.index()) + continue; + + centrality = c1.centFT0M(); + if (cfgAccCor) { + auto bc = c1.bc_as(); + AccMap = ccdb->getForTimeStamp(cfgAccCorPath.value, bc.timestamp()); + } + if (!eventSelected(c1)) + continue; + if (!eventSelected(c2)) + continue; + + auto tracks1 = V0s.sliceBy(tracksPerCollisionV0, c1.globalIndex()); + auto tracks2 = V0s.sliceBy(tracksPerCollisionV0, c2.globalIndex()); + + FillHistograms(c1, c2, tracks1, tracks2); + } + } + PROCESS_SWITCH(lambdaTwoPartPolarization, processDataMixedT0M, "Process event for mixed data in pp", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Strangeness/lambdalambda.cxx b/PWGLF/Tasks/Strangeness/lambdalambda.cxx index bf8579f105d..4c6b7bc4d84 100644 --- a/PWGLF/Tasks/Strangeness/lambdalambda.cxx +++ b/PWGLF/Tasks/Strangeness/lambdalambda.cxx @@ -11,51 +11,48 @@ /// \author Junlee Kim (jikim1290@gmail.com) -#include -#include -#include -#include -#include -#include +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "TLorentzVector.h" -#include "TRandom3.h" -#include "TF1.h" -#include "TVector3.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" -#include +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/ASoAHelpers.h" #include "Framework/StaticFor.h" - -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" - -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelection.h" - -#include "CommonConstants/PhysicsConstants.h" - +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" - -#include "CCDB/CcdbApi.h" -#include "CCDB/BasicCCDBManager.h" +#include "Math/GenVector/Boost.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "TF1.h" +#include "TLorentzVector.h" +#include "TRandom3.h" +#include "TVector3.h" +#include -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -68,6 +65,9 @@ struct lambdalambda { using TrackCandidates = soa::Join; using V0TrackCandidate = aod::V0Datas; + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + HistogramRegistry histos{ "histos", {}, @@ -136,6 +136,9 @@ struct lambdalambda { Configurable cfgNRotBkg{"cfgNRotBkg", 10, "the number of rotational backgrounds"}; Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 10, "Number of mixed events per event"}; + Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Enable processing of skimmed data"}; + Configurable cfgTriggerName{"cfgTriggerName", "fLambdaLambda", "Software trigger name"}; + ConfigurableAxis massAxis{"massAxis", {110, 2.22, 2.33}, "Invariant mass axis"}; ConfigurableAxis ptAxis{"ptAxis", {VARIABLE_WIDTH, 0.2, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.5, 8.0, 10.0, 100.0}, "Transverse momentum bins"}; ConfigurableAxis centAxis{"centAxis", {VARIABLE_WIDTH, 0, 10, 20, 50, 100}, "Centrality interval"}; @@ -157,8 +160,20 @@ struct lambdalambda { bool IsTriggered; bool IsSelected; + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (cfgSkimmedProcessing) { + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), cfgTriggerName.value); + zorro.populateHistRegistry(histos, bc.runNumber()); + } + } + void init(o2::framework::InitContext&) { + if (cfgSkimmedProcessing) { + zorroSummary.setObject(zorro.getZorroSummary()); + } + AxisSpec centQaAxis = {80, 0.0, 80.0}; AxisSpec PVzQaAxis = {300, -15.0, 15.0}; AxisSpec combAxis = {3, -0.5, 2.5}; @@ -506,8 +521,15 @@ struct lambdalambda { histos.fill(HIST("QA/CentDist"), centrality, 1.0); histos.fill(HIST("QA/PVzDist"), collision.posZ(), 1.0); + auto bc = collision.bc_as(); + if (cfgSkimmedProcessing) { + initCCDB(bc); + if (!zorro.isSelected(collision.template bc_as().globalBC())) { + return; + } + } + if (cfgEffCor) { - auto bc = collision.bc_as(); EffMap = ccdb->getForTimeStamp(cfgEffCorPath.value, bc.timestamp()); } FillHistograms(collision, collision, V0s, V0s); @@ -520,31 +542,46 @@ struct lambdalambda { PROCESS_SWITCH(lambdalambda, processDataSame, "Process Event for same data", true); SliceCache cache; - using BinningTypeVertexContributor = ColumnBinningPolicy; + using BinningType = ColumnBinningPolicy; + BinningType colBinning{{vertexAxis, centAxis}, true}; + Preslice tracksPerCollisionV0 = aod::v0data::collisionId; void processDataMixed(EventCandidates const& collisions, - TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s) + TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { - auto tracksTuple = std::make_tuple(V0s); - BinningTypeVertexContributor binningOnPositions{{vertexAxis, centAxis}, true}; - SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (auto& [c1, tracks1, c2, tracks2] : pair) { - if (cfgCentEst == 1) { - centrality = c1.centFT0C(); - } else if (cfgCentEst == 2) { - centrality = c1.centFT0M(); + int currentRun = -1; + for (auto& [c1, c2] : selfCombinations(colBinning, cfgNoMixedEvents, -1, collisions, collisions)) { + if (c1.index() == c2.index()) + continue; + + auto bc1 = c1.bc_as(); + auto bc2 = c2.bc_as(); + + if (bc1.runNumber() != bc2.runNumber()) + continue; + + if (bc1.runNumber() != currentRun) { + if (cfgSkimmedProcessing) { + initCCDB(bc1); + if (!zorro.isSelected(bc1.globalBC()) || !zorro.isSelected(bc2.globalBC())) { + continue; + } + } } + + centrality = c1.centFT0M(); if (!eventSelected(c1)) continue; if (!eventSelected(c2)) continue; - if (c1.bcId() == c2.bcId()) - continue; + + auto tracks1 = V0s.sliceBy(tracksPerCollisionV0, c1.globalIndex()); + auto tracks2 = V0s.sliceBy(tracksPerCollisionV0, c2.globalIndex()); FillHistograms(c1, c2, tracks1, tracks2); } } - PROCESS_SWITCH(lambdalambda, processDataMixed, "Process Event for mixed data", true); + PROCESS_SWITCH(lambdalambda, processDataMixed, "Process Event for mixed data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx index 1399d4d293c..4846108dc2f 100644 --- a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx +++ b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx @@ -1470,6 +1470,15 @@ struct lambdapolsp { } } } else { + + int binxwgt; + double wgtvalue; + if (useyldwgt) { + binxwgt = hwgtAL->GetXaxis()->FindBin(v0.pt()); + wgtvalue = hwgtAL->GetBinContent(binxwgt); + } else { + wgtvalue = 1.0; + } if (analyzeLambda && LambdaTag) { Lambda = Proton + AntiPion; tagb = 0; @@ -1488,7 +1497,7 @@ struct lambdapolsp { int biny = accprofileAL->GetYaxis()->FindBin(v0.pt()); double acvalue = accprofileAL->GetBinContent(binx, biny); // double acvalue = 1.0; - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue, 1.0); + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue, wgtvalue); } } } diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index 488e5815ce0..9672a65d4f8 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -209,6 +209,7 @@ struct NonPromptCascadeTask { int mRunNumber = 0; float mBz = 0.f; o2::vertexing::DCAFitterN<2> mDCAFitter; + std::array mProcessCounter = {0, 0}; // {Tracked, All} void initCCDB(aod::BCsWithTimestamps::iterator const& bc) { @@ -300,7 +301,7 @@ struct NonPromptCascadeTask { void zorroAccounting(const auto& collisions, auto& toiMap) { - if (cfgSkimmedProcessing) { + if (cfgSkimmedProcessing && mProcessCounter[0] != mProcessCounter[1]) { int runNumber{-1}; for (const auto& coll : collisions) { auto bc = coll.template bc_as(); @@ -691,6 +692,7 @@ struct NonPromptCascadeTask { aod::V0s const& /*v0s*/, TracksExtData const& tracks, aod::BCsWithTimestamps const&) { + mProcessCounter[0]++; fillMultHistos(collisions); std::map toiMap; zorroAccounting(collisions, toiMap); @@ -703,6 +705,7 @@ struct NonPromptCascadeTask { aod::V0s const& /*v0s*/, TracksExtData const& tracks, aod::BCsWithTimestamps const&) { + mProcessCounter[1]++; std::map toiMap; zorroAccounting(collisions, toiMap); fillCandidatesVector(collisions, tracks, cascades, gCandidatesNT, toiMap); diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index a59ea761daf..076609b91b9 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -17,7 +17,9 @@ #include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/inelGt.h" +#include "Common/Core/TableHelper.h" #include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -224,8 +226,9 @@ struct Phik0shortanalysis { // Configurables for dN/deta with phi computation Configurable furtherCheckonMcCollision{"furtherCheckonMcCollision", true, "Further check on MC collisions"}; - Configurable filterOnGenPhi{"filterOnGenPhi", true, "Filter on MC Phi"}; - Configurable filterOnRecoPhiWPDG{"filterOnRecoPhiWPDG", true, "Filter on Reco Phi with WPDG"}; + Configurable filterOnGenPhi{"filterOnGenPhi", 1, "Filter on Gen Phi (0: K+K- pair like Phi, 1: proper Phi)"}; + Configurable filterOnRecoPhi{"filterOnRecoPhi", 1, "Filter on Reco Phi (0: without PDG, 1: with PDG)"}; + Configurable fillMcPartsForAllReco{"fillMcPartsForAllReco", false, "Fill MC particles for all associated reco collisions"}; // Configurable for event mixing Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, "Number of mixed events per event"}; @@ -306,6 +309,9 @@ struct Phik0shortanalysis { Partition posMCTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; Partition negMCTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; + Partition posFiltMCTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; + Partition negFiltMCTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; + // Necessary to flag INEL>0 events in GenMC Service pdgDB; @@ -978,8 +984,8 @@ struct Phik0shortanalysis { return false; } - template - bool eventHasRecoPhiWPDG(const T1& posTracks, const T2& negTracks) + template + bool eventHasRecoPhiWPDG(const T1& posTracks, const T2& negTracks, const T3& mcParticles) { int nPhi = 0; @@ -991,7 +997,7 @@ struct Phik0shortanalysis { if (!track1.has_mcParticle()) continue; - auto mcTrack1 = track1.template mcParticle_as(); + auto mcTrack1 = mcParticles.rawIteratorAt(track1.mcParticleId()); if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) continue; @@ -1005,24 +1011,28 @@ struct Phik0shortanalysis { if (!track2.has_mcParticle()) continue; - auto mcTrack2 = track2.template mcParticle_as(); + auto mcTrack2 = mcParticles.rawIteratorAt(track2.mcParticleId()); if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) continue; + const auto mcTrack1MotherIndexes = mcTrack1.mothersIds(); + const auto mcTrack2MotherIndexes = mcTrack2.mothersIds(); + float pTMother = -1.0f; float yMother = -1.0f; bool isMCMotherPhi = false; - for (const auto& motherOfMcTrack1 : mcTrack1.template mothers_as()) { - for (const auto& motherOfMcTrack2 : mcTrack2.template mothers_as()) { - if (motherOfMcTrack1.pdgCode() != motherOfMcTrack2.pdgCode()) - continue; - if (motherOfMcTrack1.globalIndex() != motherOfMcTrack2.globalIndex()) + + for (const auto& mcTrack1MotherIndex : mcTrack1MotherIndexes) { + for (const auto& mcTrack2MotherIndex : mcTrack2MotherIndexes) { + if (mcTrack1MotherIndex != mcTrack2MotherIndex) continue; - if (motherOfMcTrack1.pdgCode() != o2::constants::physics::Pdg::kPhi) + + const auto mother = mcParticles.rawIteratorAt(mcTrack1MotherIndex); + if (mother.pdgCode() != o2::constants::physics::Pdg::kPhi) continue; - pTMother = motherOfMcTrack1.pt(); - yMother = motherOfMcTrack1.y(); + pTMother = mother.pt(); + yMother = mother.y(); isMCMotherPhi = true; } } @@ -1041,6 +1051,40 @@ struct Phik0shortanalysis { return false; } + template + bool eventHasGenKPair(const T& mcParticles) + { + int nKPair = 0; + + for (const auto& mcParticle1 : mcParticles) { + if (!mcParticle1.isPhysicalPrimary() || std::abs(mcParticle1.eta()) > trackConfigs.etaMax) + continue; + + for (const auto& mcParticle2 : mcParticles) { + if (!mcParticle2.isPhysicalPrimary() || std::abs(mcParticle2.eta()) > trackConfigs.etaMax) + continue; + + if ((mcParticle1.pdgCode() != PDG_t::kKPlus || mcParticle2.pdgCode() != PDG_t::kKMinus) && + (mcParticle1.pdgCode() != PDG_t::kKMinus || mcParticle2.pdgCode() != PDG_t::kKPlus)) + continue; + + ROOT::Math::PxPyPzMVector genKPair = recMother(mcParticle1, mcParticle2, massKa, massKa); + if (genKPair.Pt() < phiConfigs.minPhiPt) + continue; + if (genKPair.M() < phiConfigs.lowMPhi || genKPair.M() > phiConfigs.upMPhi) + continue; + if (std::abs(genKPair.Rapidity()) > deltaYConfigs.cfgYAcceptance) + continue; + + nKPair++; + } + } + + if (nKPair > 0) + return true; + return false; + } + template bool eventHasGenPhi(const T& mcParticles) { @@ -2652,118 +2696,155 @@ struct Phik0shortanalysis { PROCESS_SWITCH(Phik0shortanalysis, processdNdetaWPhiMCReco, "Process function for dN/deta values in MCReco", false); - void processdNdetaWPhiMCGen(MCCollisions::iterator const& mcCollision, soa::SmallGroups const& collisions, FilteredMCTracks const& filteredMCTracks, aod::McParticles const& mcParticles) + void processdNdetaWPhiMCGen(MCCollisions const& mcCollisions, SimCollisions const& collisions, FilteredMCTracks const& filteredMCTracks, aod::McParticles const& mcParticles) { - if (!pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) - return; - if (filterOnGenPhi && !eventHasGenPhi(mcParticles)) - return; - - uint64_t numberAssocColl = 0; - std::vector zVtxs; + std::vector> collsGrouped(mcCollisions.size()); for (const auto& collision : collisions) { - if (acceptEventQA(collision, false)) { - auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); - - Partition posFiltMCTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; - posFiltMCTracks.bindTable(filteredMCTracksThisColl); - Partition negFiltMCTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; - negFiltMCTracks.bindTable(filteredMCTracksThisColl); - - if (filterOnRecoPhiWPDG && !eventHasRecoPhiWPDG(posFiltMCTracks, negFiltMCTracks)) - continue; - - mcEventHist.fill(HIST("hGenMCRecoMultiplicityPercent"), mcCollision.centFT0M()); - mcEventHist.fill(HIST("h2GenMCRecoVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); + if (!collision.has_mcCollision()) + continue; + const auto& mcCollision = collision.mcCollision_as(); + collsGrouped[mcCollision.globalIndex()].push_back(collision.globalIndex()); + } - zVtxs.push_back(collision.posZ()); + for (const auto& mcCollision : mcCollisions) { + auto mcParticlesThisMcColl = mcParticles.sliceBy(preslices.perMCColl, mcCollision.globalIndex()); - for (const auto& track : filteredMCTracksThisColl) { - if (trackConfigs.applyExtraPhiCuts && ((track.phi() > trackConfigs.extraPhiCuts->at(0) && track.phi() < trackConfigs.extraPhiCuts->at(1)) || - track.phi() <= trackConfigs.extraPhiCuts->at(2) || track.phi() >= trackConfigs.extraPhiCuts->at(3))) + if (!pwglf::isINELgtNmc(mcParticlesThisMcColl, 0, pdgDB)) + continue; + switch (filterOnGenPhi) { + case 0: + if (!eventHasGenKPair(mcParticlesThisMcColl)) continue; - if (!track.has_mcParticle()) + break; + case 1: + if (!eventHasGenPhi(mcParticlesThisMcColl)) continue; + break; + default: + break; + } - auto mcTrack = track.mcParticle(); - if (!mcTrack.isPhysicalPrimary() || std::abs(mcTrack.eta()) > trackConfigs.etaMax) - continue; + uint64_t numberAssocColl = 0; + std::vector zVtxs; - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); - if (track.hasTPC()) { - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); - } else { - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); - } + auto& collIndexesThisMcColl = collsGrouped[mcCollision.globalIndex()]; - int pid = fromPDGToEnum(mcTrack.pdgCode()); - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); - } + for (const auto& collisionIndex : collIndexesThisMcColl) { + auto collision = collisions.rawIteratorAt(collisionIndex); - for (const auto& mcParticle : mcParticles) { - if (!isGenParticleCharged(mcParticle)) - continue; + if (acceptEventQA(collision, false)) { + auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); - if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); - } else { - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + posFiltMCTracks.bindTable(filteredMCTracksThisColl); + negFiltMCTracks.bindTable(filteredMCTracksThisColl); + + switch (filterOnRecoPhi) { + case 0: + if (!eventHasRecoPhi(posFiltMCTracks, negFiltMCTracks)) + continue; + break; + case 1: + if (!eventHasRecoPhiWPDG(posFiltMCTracks, negFiltMCTracks, mcParticles)) + continue; + break; + default: + break; } - int pid = fromPDGToEnum(mcParticle.pdgCode()); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); - } + mcEventHist.fill(HIST("hGenMCRecoMultiplicityPercent"), mcCollision.centFT0M()); + mcEventHist.fill(HIST("h2GenMCRecoVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); - numberAssocColl++; - } - } + zVtxs.push_back(collision.posZ()); - mcEventHist.fill(HIST("hGenMCMultiplicityPercent"), mcCollision.centFT0M()); + for (const auto& track : filteredMCTracksThisColl) { + if (trackConfigs.applyExtraPhiCuts && ((track.phi() > trackConfigs.extraPhiCuts->at(0) && track.phi() < trackConfigs.extraPhiCuts->at(1)) || + track.phi() <= trackConfigs.extraPhiCuts->at(2) || track.phi() >= trackConfigs.extraPhiCuts->at(3))) + continue; + if (!track.has_mcParticle()) + continue; - if (numberAssocColl > 0) { - float zVtxRef = zVtxs[0]; - if (zVtxs.size() > 1) { - for (size_t i = 1; i < zVtxs.size(); ++i) { - mcEventHist.fill(HIST("hSplitVertexZ"), zVtxs[i] - zVtxRef); - } - } + auto mcTrack = track.mcParticle(); + if (!mcTrack.isPhysicalPrimary() || std::abs(mcTrack.eta()) > trackConfigs.etaMax) + continue; - mcEventHist.fill(HIST("hGenMCAssocRecoMultiplicityPercent"), mcCollision.centFT0M()); - mcEventHist.fill(HIST("h2GenMCAssocRecoVertexZvsMult"), zVtxRef, mcCollision.centFT0M()); - } + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); + if (track.hasTPC()) { + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); + } else { + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); + } - for (const auto& mcParticle : mcParticles) { - if (!isGenParticleCharged(mcParticle)) - continue; + int pid = fromPDGToEnum(mcTrack.pdgCode()); + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); + } - int pid = fromPDGToEnum(mcParticle.pdgCode()); + if (fillMcPartsForAllReco) { + for (const auto& mcParticle : mcParticlesThisMcColl) { + if (!isGenParticleCharged(mcParticle)) + continue; + + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + } else { + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } - mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); - if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { - mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); - mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); - } else { - mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); - mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + int pid = fromPDGToEnum(mcParticle.pdgCode()); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + } + } + + numberAssocColl++; + } } - mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + + mcEventHist.fill(HIST("hGenMCMultiplicityPercent"), mcCollision.centFT0M()); if (numberAssocColl > 0) { float zVtxRef = zVtxs[0]; + if (zVtxs.size() > 1) { + for (size_t i = 1; i < zVtxs.size(); ++i) { + mcEventHist.fill(HIST("hSplitVertexZ"), zVtxs[i] - zVtxRef); + } + } + + mcEventHist.fill(HIST("hGenMCAssocRecoMultiplicityPercent"), mcCollision.centFT0M()); + mcEventHist.fill(HIST("h2GenMCAssocRecoVertexZvsMult"), zVtxRef, mcCollision.centFT0M()); + } + + for (const auto& mcParticle : mcParticlesThisMcColl) { + if (!isGenParticleCharged(mcParticle)) + continue; + + int pid = fromPDGToEnum(mcParticle.pdgCode()); - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); } else { - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + } else { + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); } - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); } } } diff --git a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx index c01a0a71cae..6f94ba4dd67 100644 --- a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx @@ -19,45 +19,50 @@ // gianni.shigeru.setoue.liveraro@cern.ch // -#include -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/ASoA.h" -#include "ReconstructionDataFormats/Track.h" +#include "PWGLF/DataModel/LFSigmaTables.h" +#include "PWGLF/DataModel/LFStrangenessMLTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" #include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGLF/DataModel/LFStrangenessMLTables.h" -#include "PWGLF/DataModel/LFSigmaTables.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include #include #include -#include #include #include -#include +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; -using V0MCSigmas = soa::Join; -using V0Sigmas = soa::Join; +using MCSigma0s = soa::Join; +using Sigma0s = soa::Join; -static const std::vector PhotonSels = {"NoSel", "V0Type", "DaupT", "DCADauToPV", +static const std::vector PhotonSels = {"NoSel", "V0Type", "DCADauToPV", "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", "PsiPair", "Phi", "Mass"}; @@ -69,77 +74,139 @@ static const std::vector LambdaSels = {"NoSel", "V0Radius", "DCADau static const std::vector DirList = {"BeforeSel", "AfterSel"}; struct sigmaanalysis { + Service ccdb; + ctpRateFetcher rateFetcher; + + //__________________________________________________ + // For manual sliceBy + // SliceCache cache; + PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable fillQAhistos{"fillQAhistos", false, "if true, fill QA histograms"}; + // Event level + Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; + Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; + Configurable fIRCrashOnNull{"fIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; + Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; + + struct : ConfigurableGroup { + Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; + Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", false, "reject collisions in case of pileup with another collision in the same foundBC"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds"}; + Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds"}; + Configurable requireNoCollInTimeRangeVzDep{"requireNoCollInTimeRangeVzDep", false, "reject collisions corrupted by the cannibalism, with other collisions with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ"}; + Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; + Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; + Configurable requireINEL0{"requireINEL0", false, "require INEL>0 event selection"}; + Configurable requireINEL1{"requireINEL1", false, "require INEL>1 event selection"}; + Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; + Configurable useEvtSelInDenomEff{"useEvtSelInDenomEff", false, "Consider event selections in the recoed <-> gen collision association for the denominator (or numerator) of the acc. x eff. (or signal loss)?"}; + Configurable applyZVtxSelOnMCPV{"applyZVtxSelOnMCPV", false, "Apply Z-vtx cut on the PV of the generated collision?"}; + Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; + // fast check on occupancy + Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + + // fast check on interaction rate + Configurable minIR{"minIR", -1, "minimum IR collisions"}; + Configurable maxIR{"maxIR", -1, "maximum IR collisions"}; + + } eventSelections; + + // Generated Sigma0s + Configurable mc_keepOnlyFromGenerator{"mc_keepOnlyFromGenerator", true, "if true, consider only particles from generator to calculate efficiency."}; + + // QA Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study. Only works with MC."}; - Configurable fillpTResoQAhistos{"fillpTResoQAhistos", false, "if true, fill MC QA histograms for pT resolution study. Only works with MC."}; + Configurable fillResoQAhistos{"fillResoQAhistos", false, "if true, fill MC QA histograms for pT resolution study. Only works with MC."}; // Analysis strategy: - Configurable fUseMLSel{"fUseMLSel", false, "Flag to use ML selection. If False, the standard selection is applied."}; - Configurable fselLambdaTPCPID{"fselLambdaTPCPID", true, "Flag to select lambda-like candidates using TPC NSigma."}; - Configurable fselLambdaTOFPID{"fselLambdaTOFPID", false, "Flag to select lambda-like candidates using TOF NSigma."}; Configurable doMCAssociation{"doMCAssociation", false, "Flag to process only signal candidates. Use only with processMonteCarlo!"}; + Configurable selRecoFromGenerator{"selRecoFromGenerator", false, "Flag to process only signal candidates from generator"}; Configurable doPhotonLambdaSelQA{"doPhotonLambdaSelQA", false, "Flag to fill photon and lambda QA histos!"}; - // For ML Selection - Configurable Gamma_MLThreshold{"Gamma_MLThreshold", 0.1, "Decision Threshold value to select gammas"}; - Configurable Lambda_MLThreshold{"Lambda_MLThreshold", 0.1, "Decision Threshold value to select lambdas"}; - Configurable AntiLambda_MLThreshold{"AntiLambda_MLThreshold", 0.1, "Decision Threshold value to select antilambdas"}; - - // For Standard Selection: - //// Lambda standard criteria:: - Configurable LambdaMinDCANegToPv{"LambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; - Configurable LambdaMinDCAPosToPv{"LambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; - Configurable ALambdaMinDCANegToPv{"ALambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; - Configurable ALambdaMinDCAPosToPv{"ALambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; - Configurable LambdaMaxDCAV0Dau{"LambdaMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; - Configurable LambdaMinv0radius{"LambdaMinv0radius", 0.0, "Min V0 radius (cm)"}; - Configurable LambdaMaxv0radius{"LambdaMaxv0radius", 40, "Max V0 radius (cm)"}; - Configurable LambdaMinQt{"LambdaMinQt", 0.01, "Min lambda qt value (AP plot) (GeV/c)"}; - Configurable LambdaMaxQt{"LambdaMaxQt", 0.17, "Max lambda qt value (AP plot) (GeV/c)"}; - Configurable LambdaMinAlpha{"LambdaMinAlpha", 0.25, "Min lambda alpha absolute value (AP plot)"}; - Configurable LambdaMaxAlpha{"LambdaMaxAlpha", 1.0, "Max lambda alpha absolute value (AP plot)"}; - Configurable LambdaMinv0cospa{"LambdaMinv0cospa", 0.95, "Min V0 CosPA"}; - Configurable LambdaMaxLifeTime{"LambdaMaxLifeTime", 30, "Max lifetime"}; - Configurable LambdaWindow{"LambdaWindow", 0.015, "Mass window around expected (in GeV/c2)"}; - Configurable LambdaMaxRap{"LambdaMaxRap", 0.8, "Max lambda rapidity"}; - Configurable LambdaMaxDauEta{"LambdaMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; - Configurable LambdaMaxTPCNSigmas{"LambdaMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; - Configurable LambdaPrMaxTOFNSigmas{"LambdaPrMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; - Configurable LambdaPiMaxTOFNSigmas{"LambdaPiMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; - Configurable LambdaMinTPCCrossedRows{"LambdaMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; - Configurable LambdaMinITSclusters{"LambdaMinITSclusters", 1, "minimum ITS clusters"}; - Configurable LambdaRejectPosITSafterburner{"LambdaRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; - Configurable LambdaRejectNegITSafterburner{"LambdaRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; - - //// Photon standard criteria: - Configurable Photonv0TypeSel{"Photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; - Configurable PhotonDauMinPt{"PhotonDauMinPt", 0.0, "Min daughter pT (GeV/c)"}; - Configurable PhotonMinDCADauToPv{"PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; - Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; - Configurable PhotonMinTPCCrossedRows{"PhotonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; - Configurable PhotonMinTPCNSigmas{"PhotonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; - Configurable PhotonMaxTPCNSigmas{"PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; - Configurable PhotonMinPt{"PhotonMinPt", 0.0, "Min photon pT (GeV/c)"}; - Configurable PhotonMaxPt{"PhotonMaxPt", 50.0, "Max photon pT (GeV/c)"}; - Configurable PhotonMaxRap{"PhotonMaxRap", 0.5, "Max photon rapidity"}; - Configurable PhotonMinRadius{"PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; - Configurable PhotonMaxRadius{"PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; - Configurable PhotonMaxZ{"PhotonMaxZ", 240, "Max photon conversion point z value (cm)"}; - Configurable PhotonMaxQt{"PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; - Configurable PhotonMaxAlpha{"PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; - Configurable PhotonMinV0cospa{"PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; - Configurable PhotonMaxMass{"PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; - Configurable PhotonPsiPairMax{"PhotonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; - Configurable PhotonMaxDauEta{"PhotonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; - Configurable PhotonLineCutZ0{"PhotonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; - Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; - - Configurable SigmaMaxRap{"SigmaMaxRap", 0.5, "Max sigma0 rapidity"}; + // For Selection: + //// Lambda criteria:: + struct : ConfigurableGroup { + Configurable Lambda_MLThreshold{"Lambda_MLThreshold", 0.1, "Decision Threshold value to select lambdas"}; + Configurable AntiLambda_MLThreshold{"AntiLambda_MLThreshold", 0.1, "Decision Threshold value to select antilambdas"}; + Configurable LambdaMinDCANegToPv{"LambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; + Configurable LambdaMinDCAPosToPv{"LambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; + Configurable ALambdaMinDCANegToPv{"ALambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; + Configurable ALambdaMinDCAPosToPv{"ALambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; + Configurable LambdaMaxDCAV0Dau{"LambdaMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; + Configurable LambdaMinv0radius{"LambdaMinv0radius", 0.0, "Min V0 radius (cm)"}; + Configurable LambdaMaxv0radius{"LambdaMaxv0radius", 40, "Max V0 radius (cm)"}; + Configurable LambdaMinQt{"LambdaMinQt", 0.01, "Min lambda qt value (AP plot) (GeV/c)"}; + Configurable LambdaMaxQt{"LambdaMaxQt", 0.17, "Max lambda qt value (AP plot) (GeV/c)"}; + Configurable LambdaMinAlpha{"LambdaMinAlpha", 0.25, "Min lambda alpha absolute value (AP plot)"}; + Configurable LambdaMaxAlpha{"LambdaMaxAlpha", 1.0, "Max lambda alpha absolute value (AP plot)"}; + Configurable LambdaMinv0cospa{"LambdaMinv0cospa", 0.95, "Min V0 CosPA"}; + Configurable LambdaMaxLifeTime{"LambdaMaxLifeTime", 30, "Max lifetime"}; + Configurable LambdaWindow{"LambdaWindow", 0.015, "Mass window around expected (in GeV/c2)"}; + Configurable LambdaMaxRap{"LambdaMaxRap", 0.8, "Max lambda rapidity"}; + Configurable LambdaMaxDauEta{"LambdaMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable fselLambdaTPCPID{"fselLambdaTPCPID", true, "Flag to select lambda-like candidates using TPC NSigma."}; + Configurable fselLambdaTOFPID{"fselLambdaTOFPID", false, "Flag to select lambda-like candidates using TOF NSigma."}; + Configurable LambdaMaxTPCNSigmas{"LambdaMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; + Configurable LambdaPrMaxTOFNSigmas{"LambdaPrMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; + Configurable LambdaPiMaxTOFNSigmas{"LambdaPiMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; + Configurable LambdaMinTPCCrossedRows{"LambdaMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; + Configurable LambdaMinITSclusters{"LambdaMinITSclusters", 1, "minimum ITS clusters"}; + Configurable LambdaRejectPosITSafterburner{"LambdaRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; + Configurable LambdaRejectNegITSafterburner{"LambdaRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; + + } lambdaSelections; + + //// Photon criteria: + struct : ConfigurableGroup { + Configurable Gamma_MLThreshold{"Gamma_MLThreshold", 0.1, "Decision Threshold value to select gammas"}; + Configurable Photonv0TypeSel{"Photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable PhotonMinDCADauToPv{"PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; + Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; + Configurable PhotonMinTPCCrossedRows{"PhotonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; + Configurable PhotonMinTPCNSigmas{"PhotonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; + Configurable PhotonMaxTPCNSigmas{"PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; + Configurable PhotonMinPt{"PhotonMinPt", 0.0, "Min photon pT (GeV/c)"}; + Configurable PhotonMaxPt{"PhotonMaxPt", 50.0, "Max photon pT (GeV/c)"}; + Configurable PhotonMaxRap{"PhotonMaxRap", 0.5, "Max photon rapidity"}; + Configurable PhotonMinRadius{"PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; + Configurable PhotonMaxRadius{"PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; + Configurable PhotonMaxZ{"PhotonMaxZ", 240, "Max photon conversion point z value (cm)"}; + Configurable PhotonMaxQt{"PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; + Configurable PhotonMaxAlpha{"PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; + Configurable PhotonMinV0cospa{"PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; + Configurable PhotonMaxMass{"PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; + Configurable PhotonPsiPairMax{"PhotonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; + Configurable PhotonMaxDauEta{"PhotonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable PhotonLineCutZ0{"PhotonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; + Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; + Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; + } photonSelections; + + struct : ConfigurableGroup { + Configurable Sigma0MaxRap{"Sigma0MaxRap", 0.5, "Max sigma0 rapidity"}; + Configurable Sigma0MaxRadius{"Sigma0MaxRadius", 200, "Max sigma0 decay radius"}; + Configurable Sigma0MaxDCADau{"Sigma0MaxDCADau", 50, "Max sigma0 DCA between daughters"}; + Configurable Sigma0MaxOPAngle{"Sigma0MaxOPAngle", 7, "Max sigma0 OP Angle between daughters"}; + } sigma0Selections; + + struct : ConfigurableGroup { + Configurable Pi0MaxRap{"Pi0MaxRap", 0.5, "Max sigma0 rapidity"}; + Configurable Pi0MaxRadius{"Pi0MaxRadius", 200, "Max sigma0 decay radius"}; + Configurable Pi0MaxDCADau{"Pi0MaxDCADau", 50, "Max sigma0 DCA between daughters"}; + } pi0Selections; // Axis // base properties @@ -149,11 +216,14 @@ struct sigmaanalysis { ConfigurableAxis axisDeltaPt{"axisDeltaPt", {400, -50.0, 50.0}, ""}; ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; ConfigurableAxis axisIRBinning{"axisIRBinning", {150, 0, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisNch{"axisNch", {300, 0.0f, 3000.0f}, "N_{ch}"}; + ConfigurableAxis axisGeneratorIds{"axisGeneratorIds", {256, -0.5f, 255.5f}, "axis for generatorIds"}; // Invariant Mass ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.05f, 1.151f}, "M_{#Lambda} (GeV/c^{2})"}; ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, -0.1f, 0.5f}, "M_{#Gamma}"}; + ConfigurableAxis axisPi0Mass{"axisPi0Mass", {200, 0.08f, 0.18f}, "M_{#Pi^{0}}"}; // AP plot axes ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; @@ -168,7 +238,8 @@ struct sigmaanalysis { ConfigurableAxis axisLifetime{"axisLifetime", {100, 0, 100}, "Chi2 Per Ncl"}; // topological variable QA axes - ConfigurableAxis axisRadius{"axisRadius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; + ConfigurableAxis axisV0Radius{"axisV0Radius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; + ConfigurableAxis axisV0PairRadius{"axisV0PairRadius", {200, 0.0f, 20.0f}, "V0Pair radius (cm)"}; ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; ConfigurableAxis axisCosPA{"axisCosPA", {200, 0.5f, 1.0f}, "Cosine of pointing angle"}; @@ -184,173 +255,586 @@ struct sigmaanalysis { void init(InitContext const&) { + LOGF(info, "Initializing now: cross-checking correctness..."); + if ((doprocessRealData + doprocessMonteCarlo + doprocessPi0RealData + doprocessPi0MonteCarlo > 1) || + (doprocessGeneratedRun3 + doprocessPi0GeneratedRun3 > 1)) { + LOGF(fatal, "You have enabled more than one process function. Please check your configuration! Aborting now."); + } - for (const auto& histodir : DirList) { - - histos.add(histodir + "/Photon/hTrackCode", "hTrackCode", kTH1F, {{11, 0.5f, 11.5f}}); - histos.add(histodir + "/Photon/hV0Type", "hV0Type", kTH1F, {{8, 0.5f, 8.5f}}); - histos.add(histodir + "/Photon/hNegpT", "hNegpT", kTH1F, {axisPt}); - histos.add(histodir + "/Photon/hPospT", "hPospT", kTH1F, {axisPt}); - histos.add(histodir + "/Photon/hDCANegToPV", "hDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Photon/hDCAPosToPV", "hDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Photon/hDCADau", "hDCADau", kTH1F, {axisDCAdau}); - histos.add(histodir + "/Photon/hPosTPCCR", "hPosTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Photon/hNegTPCCR", "hNegTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Photon/h2dPosTPCNSigmaEl", "h2dPosTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/h2dNegTPCNSigmaEl", "h2dNegTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/h2dPosTPCNSigmaPi", "h2dPosTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/h2dNegTPCNSigmaPi", "h2dNegTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/hpT", "hpT", kTH1F, {axisPt}); - histos.add(histodir + "/Photon/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/Photon/hPosEta", "hPosEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Photon/hNegEta", "hNegEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Photon/hRadius", "hRadius", kTH1F, {axisRadius}); - histos.add(histodir + "/Photon/hZ", "hZ", kTH1F, {axisZ}); - histos.add(histodir + "/Photon/h2dRZCut", "h2dRZCut", kTH2F, {axisZ, axisRadius}); - histos.add(histodir + "/Photon/h2dRZPlane", "h2dRZPlane", kTH2F, {axisZ, axisRadius}); - histos.add(histodir + "/Photon/hCosPA", "hCosPA", kTH1F, {axisCosPA}); - histos.add(histodir + "/Photon/hPsiPair", "hPsiPair", kTH1F, {axisPsiPair}); - histos.add(histodir + "/Photon/hPhi", "hPhi", kTH1F, {axisPhi}); - histos.add(histodir + "/Photon/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisPhotonMass}); - histos.add(histodir + "/Photon/hMass", "hMass", kTH1F, {axisPhotonMass}); - - histos.add(histodir + "/Lambda/hTrackCode", "hTrackCode", kTH1F, {{11, 0.5f, 11.5f}}); - histos.add(histodir + "/Lambda/hRadius", "hRadius", kTH1F, {axisRadius}); - histos.add(histodir + "/Lambda/hDCADau", "hDCADau", kTH1F, {axisDCAdau}); - histos.add(histodir + "/Lambda/hCosPA", "hCosPA", kTH1F, {axisCosPA}); - histos.add(histodir + "/Lambda/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/Lambda/hPosEta", "hPosEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Lambda/hNegEta", "hNegEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Lambda/hPosTPCCR", "hPosTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Lambda/hNegTPCCR", "hNegTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Lambda/hPosITSCls", "hPosITSCls", kTH1F, {axisNCls}); - histos.add(histodir + "/Lambda/hNegITSCls", "hNegITSCls", kTH1F, {axisNCls}); - histos.add(histodir + "/Lambda/hPosChi2PerNc", "hPosChi2PerNc", kTH1F, {axisChi2PerNcl}); - histos.add(histodir + "/Lambda/hNegChi2PerNc", "hNegChi2PerNc", kTH1F, {axisChi2PerNcl}); - histos.add(histodir + "/Lambda/hLifeTime", "hLifeTime", kTH1F, {axisLifetime}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hLambdapT", "hLambdapT", kTH1F, {axisPt}); - histos.add(histodir + "/Lambda/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); - histos.add(histodir + "/Lambda/h3dLambdaMass", "h3dLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/hALambdaDCANegToPV", "hALambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hALambdaDCAPosToPV", "hALambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hALambdapT", "hALambdapT", kTH1F, {axisPt}); - histos.add(histodir + "/Lambda/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); - histos.add(histodir + "/Lambda/h3dAntiLambdaMass", "h3dAntiLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - - histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); - - histos.add(histodir + "/Sigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/Sigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/Sigma0/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/Sigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add(histodir + "/Sigma0/h3dPhotonRadiusVsMassSigma", "h3dPhotonRadiusVsMassSigma", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); - histos.add(histodir + "/Sigma0/h2dpTVsOPAngle", "h2dpTVsOPAngle", kTH2F, {axisPt, {140, 0.0f, +7.0f}}); - - histos.add(histodir + "/ASigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/ASigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/ASigma0/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/ASigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add(histodir + "/ASigma0/h3dPhotonRadiusVsMassSigma", "h3dPhotonRadiusVsMassSigma", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); - histos.add(histodir + "/ASigma0/h2dpTVsOPAngle", "h2dpTVsOPAngle", kTH2F, {axisPt, {140, 0.0f, +7.0f}}); - - // Process MC - if (doprocessMonteCarlo) { - histos.add(histodir + "/MC/Photon/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); - histos.add(histodir + "/MC/Photon/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Photon/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Photon/h2dPosTPCNSigmaEl", "h2dPosTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dNegTPCNSigmaEl", "h2dNegTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dPosTPCNSigmaPi", "h2dPosTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dNegTPCNSigmaPi", "h2dNegTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dPAVsPt", "h2dPAVsPt", kTH2F, {axisPA, axisPt}); - histos.add(histodir + "/MC/Photon/hPt_BadCollAssig", "hPt_BadCollAssig", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Photon/h2dPAVsPt_BadCollAssig", "h2dPAVsPt_BadCollAssig", kTH2F, {axisPA, axisPt}); - - histos.add(histodir + "/MC/Lambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); - histos.add(histodir + "/MC/Lambda/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Lambda/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - - histos.add(histodir + "/MC/ALambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); - histos.add(histodir + "/MC/ALambda/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ALambda/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - - histos.add(histodir + "/MC/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); - - histos.add(histodir + "/MC/Sigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Sigma0/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Sigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/Sigma0/h2dMCPtVsGammaMCPt", "h2dMCPtVsGammaMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/Sigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/MC/Sigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - - histos.add(histodir + "/MC/ASigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ASigma0/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ASigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/ASigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/ASigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/MC/ASigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - - // 1/pT Resolution: - if (fillpTResoQAhistos && histodir == "BeforeSel") { - histos.add(histodir + "/MC/pTReso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h2dAntiLambdaPtResolution", "h2dAntiLambdaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h2dSigma0PtResolution", "h2dSigma0PtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h2dAntiSigma0PtResolution", "h2dAntiSigma0PtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + // setting CCDB service + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); + + // Event Counters + histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + + histos.add("hEventSelection", "hEventSelection", kTH1D, {{21, -0.5f, +20.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); + if (doPPAnalysis) { + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "INEL>0"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "INEL>1"); + } else { + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); + } + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(19, "Below min IR"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(20, "Above max IR"); + + if (fGetIR) { + histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); + histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1D, {axisIRBinning}); + histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2D, {axisCentrality, axisIRBinning}); + } + + if (doprocessRealData || doprocessMonteCarlo) { + for (const auto& histodir : DirList) { + + histos.add(histodir + "/Photon/hTrackCode", "hTrackCode", kTH1D, {{11, 0.5f, 11.5f}}); + histos.add(histodir + "/Photon/hV0Type", "hV0Type", kTH1D, {{8, 0.5f, 8.5f}}); + histos.add(histodir + "/Photon/hDCANegToPV", "hDCANegToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Photon/hDCAPosToPV", "hDCAPosToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Photon/hDCADau", "hDCADau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/Photon/hPosTPCCR", "hPosTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Photon/hNegTPCCR", "hNegTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Photon/hPosTPCNSigmaEl", "hPosTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + histos.add(histodir + "/Photon/hNegTPCNSigmaEl", "hNegTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + + histos.add(histodir + "/Photon/hpT", "hpT", kTH1D, {axisPt}); + histos.add(histodir + "/Photon/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/Photon/hPosEta", "hPosEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Photon/hNegEta", "hNegEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Photon/hRadius", "hRadius", kTH1D, {axisV0Radius}); + histos.add(histodir + "/Photon/hZ", "hZ", kTH1D, {axisZ}); + histos.add(histodir + "/Photon/h2dRZCut", "h2dRZCut", kTH2D, {axisZ, axisV0Radius}); + histos.add(histodir + "/Photon/h2dRZPlane", "h2dRZPlane", kTH2D, {axisZ, axisV0Radius}); + histos.add(histodir + "/Photon/hCosPA", "hCosPA", kTH1D, {axisCosPA}); + histos.add(histodir + "/Photon/hPsiPair", "hPsiPair", kTH1D, {axisPsiPair}); + histos.add(histodir + "/Photon/hPhi", "hPhi", kTH1D, {axisPhi}); + histos.add(histodir + "/Photon/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisPhotonMass}); + histos.add(histodir + "/Photon/hMass", "hMass", kTH1D, {axisPhotonMass}); + + histos.add(histodir + "/Lambda/hTrackCode", "hTrackCode", kTH1D, {{11, 0.5f, 11.5f}}); + histos.add(histodir + "/Lambda/hRadius", "hRadius", kTH1D, {axisV0Radius}); + histos.add(histodir + "/Lambda/hDCADau", "hDCADau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/Lambda/hCosPA", "hCosPA", kTH1D, {axisCosPA}); + histos.add(histodir + "/Lambda/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/Lambda/hPosEta", "hPosEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Lambda/hNegEta", "hNegEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Lambda/hPosTPCCR", "hPosTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Lambda/hNegTPCCR", "hNegTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Lambda/hPosITSCls", "hPosITSCls", kTH1D, {axisNCls}); + histos.add(histodir + "/Lambda/hNegITSCls", "hNegITSCls", kTH1D, {axisNCls}); + histos.add(histodir + "/Lambda/hPosChi2PerNc", "hPosChi2PerNc", kTH1D, {axisChi2PerNcl}); + histos.add(histodir + "/Lambda/hNegChi2PerNc", "hNegChi2PerNc", kTH1D, {axisChi2PerNcl}); + histos.add(histodir + "/Lambda/hLifeTime", "hLifeTime", kTH1D, {axisLifetime}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hLambdapT", "hLambdapT", kTH1D, {axisPt}); + histos.add(histodir + "/Lambda/hLambdaMass", "hLambdaMass", kTH1D, {axisLambdaMass}); + histos.add(histodir + "/Lambda/h3dLambdaMass", "h3dLambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/hALambdaDCANegToPV", "hALambdaDCANegToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hALambdaDCAPosToPV", "hALambdaDCAPosToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hALambdapT", "hALambdapT", kTH1D, {axisPt}); + histos.add(histodir + "/Lambda/hAntiLambdaMass", "hAntiLambdaMass", kTH1D, {axisLambdaMass}); + histos.add(histodir + "/Lambda/h3dAntiLambdaMass", "h3dAntiLambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); + + histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2D, {axisAPAlpha, axisAPQt}); + + histos.add(histodir + "/Sigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/Sigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/Sigma0/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/Sigma0/hRadius", "hRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/Sigma0/h2dRadiusVspT", "h2dRadiusVspT", kTH2D, {axisV0PairRadius, axisPt}); + histos.add(histodir + "/Sigma0/hDCAPairDau", "hDCAPairDau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/Sigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/Sigma0/h3dOPAngleVsMass", "h3dOPAngleVsMass", kTH3D, {{140, 0.0f, +7.0f}, axisPt, axisSigmaMass}); + + histos.add(histodir + "/ASigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/ASigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/ASigma0/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/ASigma0/hRadius", "hRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/ASigma0/h2dRadiusVspT", "h2dRadiusVspT", kTH2D, {axisV0PairRadius, axisPt}); + histos.add(histodir + "/ASigma0/hDCAPairDau", "hDCAPairDau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/ASigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/ASigma0/h3dOPAngleVsMass", "h3dOPAngleVsMass", kTH3D, {{140, 0.0f, +7.0f}, axisPt, axisSigmaMass}); + + // Process MC + if (doprocessMonteCarlo) { + histos.add(histodir + "/MC/Photon/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1D, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/Photon/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Photon/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Photon/hPosTPCNSigmaEl", "hPosTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/hNegTPCNSigmaEl", "hNegTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/h2dPAVsPt", "h2dPAVsPt", kTH2D, {axisPA, axisPt}); + histos.add(histodir + "/MC/Photon/hPt_BadCollAssig", "hPt_BadCollAssig", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Photon/h2dPAVsPt_BadCollAssig", "h2dPAVsPt_BadCollAssig", kTH2D, {axisPA, axisPt}); + + histos.add(histodir + "/MC/Lambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1D, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/Lambda/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Lambda/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + + histos.add(histodir + "/MC/ALambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1D, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/ALambda/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ALambda/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + + histos.add(histodir + "/MC/h2dArmenteros", "h2dArmenteros", kTH2D, {axisAPAlpha, axisAPQt}); + + histos.add(histodir + "/MC/Sigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Sigma0/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Sigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/MC/Sigma0/hMCProcess", "hMCProcess", kTH1D, {{50, -0.5f, 49.5f}}); + histos.add(histodir + "/MC/Sigma0/hGenRadius", "hGenRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/MC/Sigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/Sigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/Sigma0/h2dMCProcessVsGenRadius", "h2dMCProcessVsGenRadius", kTH2D, {{50, -0.5f, 49.5f}, axisV0PairRadius}); + histos.add(histodir + "/MC/Sigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/Sigma0/h3dMCProcess", "h3dMCProcess", kTH3D, {{50, -0.5f, 49.5f}, axisPt, axisSigmaMass}); + + histos.add(histodir + "/MC/ASigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ASigma0/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ASigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/MC/ASigma0/hMCProcess", "hMCProcess", kTH1D, {{50, -0.5f, 49.5f}}); + histos.add(histodir + "/MC/ASigma0/hGenRadius", "hGenRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/MC/ASigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/ASigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/ASigma0/h2dMCProcessVsGenRadius", "h2dMCProcessVsGenRadius", kTH2D, {{50, -0.5f, 49.5f}, axisV0PairRadius}); + histos.add(histodir + "/MC/ASigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/ASigma0/h3dMCProcess", "h3dMCProcess", kTH3D, {{50, -0.5f, 49.5f}, axisPt, axisSigmaMass}); + + // 1/pT Resolution: + if (fillResoQAhistos && histodir == "BeforeSel") { + histos.add(histodir + "/MC/Reso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dAntiLambdaPtResolution", "h2dAntiLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dSigma0PtResolution", "h2dSigma0PtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dAntiSigma0PtResolution", "h2dAntiSigma0PtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dSigma0RadiusResolution", "h2dSigma0RadiusResolution", kTH2D, {axisPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dASigma0RadiusResolution", "h2dASigma0RadiusResolution", kTH2D, {axisPt, axisDeltaPt}); + } + + // For background decomposition study + if (fillBkgQAhistos) { + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + } } + } + + // Selections + histos.add("Selection/Photon/hCandidateSel", "hCandidateSel", kTH1D, {axisCandSel}); + histos.add("Selection/Lambda/hCandidateSel", "hCandidateSel", kTH1D, {axisCandSel}); + + // For background decomposition study + if (fillBkgQAhistos && doprocessMonteCarlo) { + histos.add("BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + } + + for (size_t i = 0; i < PhotonSels.size(); ++i) { + const auto& sel = PhotonSels[i]; + + histos.add(Form("Selection/Photon/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2D, {axisPt, axisPhotonMass}); + histos.get(HIST("Selection/Photon/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); + histos.add(Form("Selection/Sigma0/h2dPhoton%s", sel.c_str()), ("h2dPhoton" + sel).c_str(), kTH2D, {axisPt, axisSigmaMass}); + } + + for (size_t i = 0; i < LambdaSels.size(); ++i) { + const auto& sel = LambdaSels[i]; - // For background decomposition study - if (fillBkgQAhistos) { - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2F, {axisPt, axisSigmaMass}); + histos.add(Form("Selection/Lambda/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2D, {axisPt, axisLambdaMass}); + histos.get(HIST("Selection/Lambda/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); + histos.add(Form("Selection/Sigma0/h2dLambda%s", sel.c_str()), ("h2dLambda" + sel).c_str(), kTH2D, {axisPt, axisSigmaMass}); + } + } + + if (doprocessPi0RealData || doprocessPi0MonteCarlo) { + histos.add("Pi0/hMass", "hMass", kTH1D, {axisPi0Mass}); + histos.add("Pi0/hPt", "hPt", kTH1D, {axisPt}); + histos.add("Pi0/hY", "hY", kTH1D, {axisRapidity}); + histos.add("Pi0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); + histos.add("Pi0/h3dMass_MCAssociated", "h3dMass_MCAssociated", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); + } + + if (doprocessGeneratedRun3 || doprocessPi0GeneratedRun3) { + + histos.add("Gen/hGenEvents", "hGenEvents", kTH2D, {{axisNch}, {2, -0.5f, +1.5f}}); + histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(1, "All gen. events"); + histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(2, "Gen. with at least 1 rec. events"); + + histos.add("Gen/hGenEventCentrality", "hGenEventCentrality", kTH1D, {axisCentrality}); + histos.add("Gen/hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", kTH2D, {axisCentrality, {50, -0.5f, 49.5f}}); + histos.add("Gen/hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", kTH2D, {axisCentrality, {50, -0.5f, 49.5f}}); + histos.add("Gen/hCentralityVsMultMC", "hCentralityVsMultMC", kTH2D, {axisCentrality, axisNch}); + + histos.add("Gen/hEventPVzMC", "hEventPVzMC", kTH1D, {{100, -20.0f, +20.0f}}); + histos.add("Gen/hCentralityVsPVzMC", "hCentralityVsPVzMC", kTH2D, {{101, 0.0f, 101.0f}, {100, -20.0f, +20.0f}}); + + // Sigma0 specific + if (doprocessGeneratedRun3) { + histos.add("Gen/h2dGenSigma0", "h2dGenSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("Gen/h2dGenAntiSigma0", "h2dGenAntiSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("Gen/h2dGenSigma0VsMultMC_RecoedEvt", "h2dGenSigma0VsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenAntiSigma0VsMultMC_RecoedEvt", "h2dGenAntiSigma0VsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenSigma0VsMultMC", "h2dGenSigma0VsMultMC", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenAntiSigma0VsMultMC", "h2dGenAntiSigma0VsMultMC", kTH2D, {axisNch, axisPt}); + + } else { // Pi0 specific + histos.add("Gen/h2dGenPi0VsMultMC_RecoedEvt", "h2dGenPi0VsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenPi0", "h2dGenPi0", kTH2D, {axisCentrality, axisPt}); + histos.add("Gen/h2dGenPi0VsMultMC", "h2dGenPi0VsMultMC", kTH2D, {axisNch, axisPt}); + } + } + } + + // ______________________________________________________ + // Check whether the collision passes our collision selections + // Should work with collisions, mccollisions, stracollisions and stramccollisions tables! + template + bool IsEventAccepted(TCollision const& collision, bool fillHists) + { + if (fillHists) + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + if (eventSelections.requireSel8 && !collision.sel8()) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + if (eventSelections.requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); + if (eventSelections.rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); + if (eventSelections.rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + if (std::abs(collision.posZ()) > eventSelections.maxZVtxPosition) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); + if (eventSelections.requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); + if (eventSelections.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); + if (eventSelections.requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); + if (eventSelections.requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); + if (eventSelections.rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); + if (eventSelections.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); + if (eventSelections.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); + if (eventSelections.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); + if (eventSelections.requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); + if (eventSelections.requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && collision.multNTracksPVeta1() < 1) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* INEL > 0 */); + if (eventSelections.requireINEL1 && collision.multNTracksPVeta1() < 2) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* INEL > 1 */); + } else { // we are in Pb-Pb + float collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); + if (eventSelections.minOccupancy >= 0 && collisionOccupancy < eventSelections.minOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); + if (eventSelections.maxOccupancy >= 0 && collisionOccupancy > eventSelections.maxOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); + } + + // Fetch interaction rate only if required (in order to limit ccdb calls) + float interactionRate = (fGetIR) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + if (fGetIR) { + if (interactionRate < 0) + histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", collision.runNumber()), 1); // This lists all run numbers without IR info! + + histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); + histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); + } + + if (eventSelections.minIR >= 0 && interactionRate < eventSelections.minIR) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 18 /* Below min IR */); + + if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); + + // Fill centrality histogram after event selection + if (fillHists) + histos.fill(HIST("hEventCentrality"), centrality); + + return true; + } + + // ______________________________________________________ + // Simulated processing + // Return the list of indices to the recoed collision associated to a given MC collision. + template + std::vector getListOfRecoCollIndices(TMCollisions const& mcCollisions, TCollisions const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + int biggestNContribs = -1; + int bestCollisionIndex = -1; + for (auto const& collision : groupedCollisions) { + // consider event selections in the recoed <-> gen collision association, for the denominator (or numerator) of the efficiency (or signal loss)? + if (eventSelections.useEvtSelInDenomEff) { + if (!IsEventAccepted(collision, false)) { + continue; + } + } + // Find the collision with the biggest nbr of PV contributors + // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + bestCollisionIndex = collision.globalIndex(); } } + listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; } + return listBestCollisionIdx; + } - // Selections - histos.add("Selection/Photon/hCandidateSel", "hCandidateSel", kTH1F, {axisCandSel}); - histos.add("Selection/Lambda/hCandidateSel", "hCandidateSel", kTH1F, {axisCandSel}); + // ______________________________________________________ + // Simulated processing + // Fill generated event information (for event loss/splitting estimation) + template + void fillGeneratedEventProperties(TMCCollisions const& mcCollisions, TCollisions const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + // Apply selections on MC collisions + if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { + continue; + } + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { + continue; + } + + if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { + continue; + } + } - for (size_t i = 0; i < PhotonSels.size(); ++i) { - const auto& sel = PhotonSels[i]; + histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 0 /* all gen. events*/); - histos.add(Form("Selection/Photon/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2F, {axisPt, axisPhotonMass}); - histos.get(HIST("Selection/Photon/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); - histos.add(Form("Selection/Sigma0/h2dPhoton%s", sel.c_str()), ("h2dPhoton" + sel).c_str(), kTH2F, {axisPt, axisSigmaMass}); + auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + // Check if there is at least one of the reconstructed collisions associated to this MC collision + // If so, we consider it + bool atLeastOne = false; + int biggestNContribs = -1; + float centrality = 100.5f; + int nCollisions = 0; + for (auto const& collision : groupedCollisions) { + + if (!IsEventAccepted(collision, false)) { + continue; + } + + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + } + + nCollisions++; + atLeastOne = true; + } + + histos.fill(HIST("Gen/hCentralityVsNcoll_beforeEvSel"), centrality, groupedCollisions.size()); + histos.fill(HIST("Gen/hCentralityVsNcoll_afterEvSel"), centrality, nCollisions); + histos.fill(HIST("Gen/hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); + histos.fill(HIST("Gen/hCentralityVsPVzMC"), centrality, mcCollision.posZ()); + histos.fill(HIST("Gen/hEventPVzMC"), mcCollision.posZ()); + + if (atLeastOne) { + histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); + histos.fill(HIST("Gen/hGenEventCentrality"), centrality); + } } + return; + } + + // ______________________________________________________ + // Simulated processing (subscribes to MC information too) + template + void analyzeGenerated(TMCCollisions const& mcCollisions, TCollisions const& collisions, TGenParticles const& genParticles) + { + fillGeneratedEventProperties(mcCollisions, collisions); + std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, collisions); + + for (auto& genParticle : genParticles) { + float centrality = 100.5f; - for (size_t i = 0; i < LambdaSels.size(); ++i) { - const auto& sel = LambdaSels[i]; + // Has MC collision + if (!genParticle.has_straMCCollision()) + continue; + + // Selection on the source (generator/transport) + if (!genParticle.producedByGenerator() && mc_keepOnlyFromGenerator) + continue; + + // Select corresponding mc collision && Basic event selection + auto mcCollision = genParticle.template straMCCollision_as>(); + if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { + continue; + } + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { + continue; + } - histos.add(Form("Selection/Lambda/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2F, {axisPt, axisLambdaMass}); - histos.get(HIST("Selection/Lambda/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); - histos.add(Form("Selection/Sigma0/h2dLambda%s", sel.c_str()), ("h2dLambda" + sel).c_str(), kTH2F, {axisPt, axisSigmaMass}); + if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { + continue; + } + } + + //______________________________________________________________________________ + // Generated Sigma0 processing + if constexpr (requires { genParticle.sigma0MCPt(); }) { + + float ptmc = genParticle.sigma0MCPt(); + + if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { + auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); + centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + if (genParticle.isSigma0()) + histos.fill(HIST("Gen/h2dGenSigma0VsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + + else + histos.fill(HIST("Gen/h2dGenAntiSigma0VsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + + if (genParticle.isSigma0()) { + histos.fill(HIST("Gen/h2dGenSigma0"), centrality, ptmc); + histos.fill(HIST("Gen/h2dGenSigma0VsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } else { + histos.fill(HIST("Gen/h2dGenAntiSigma0"), centrality, ptmc); + histos.fill(HIST("Gen/h2dGenAntiSigma0VsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } + } + //______________________________________________________________________________ + // Generated Pi0 processing + if constexpr (requires { genParticle.pi0MCPt(); }) { + float ptmc = genParticle.pi0MCPt(); + + if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { + auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); + centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + histos.fill(HIST("Gen/h2dGenPi0VsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + + histos.fill(HIST("Gen/h2dGenPi0"), centrality, ptmc); + histos.fill(HIST("Gen/h2dGenPi0VsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } } } //__________________________________________ - template - int retrieveV0TrackCode(TV0Object const& sigma) + template + int retrieveV0TrackCode(TSigma0Object const& sigma) { int TrkCode = 10; // 1: TPC-only, 2: TPC+Something, 3: ITS-Only, 4: ITS+TPC + Something, 10: anything else @@ -378,67 +862,69 @@ struct sigmaanalysis { return TrkCode; } - template - void getpTResolution(TV0Object const& sigma) + template + void getResolution(TSigma0Object const& sigma) { //_______________________________________ // Gamma MC association - if (sigma.photonCandPDGCode() == 22) { - if (sigma.photonMCPt() > 0) { - histos.fill(HIST("BeforeSel/MC/pTReso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.photonNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.photonPosTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h2dGammaPtResolution"), 1.f / sigma.photonMCPt(), 1.f / sigma.photonPt() - 1.f / sigma.photonMCPt()); // pT resolution + if (sigma.photonPDGCode() == 22) { + if (sigma.photonmcpt() > 0) { + histos.fill(HIST("BeforeSel/MC/Reso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), -1 * sigma.photonNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), sigma.photonPosTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h2dGammaPtResolution"), 1.f / sigma.photonmcpt(), 1.f / sigma.photonPt() - 1.f / sigma.photonmcpt()); // pT resolution } } //_______________________________________ // Lambda MC association - if (sigma.lambdaCandPDGCode() == 3122) { - if (sigma.lambdaMCPt() > 0) { - histos.fill(HIST("BeforeSel/MC/pTReso/h2dLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution + if (sigma.lambdaPDGCode() == 3122) { + if (sigma.lambdamcpt() > 0) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dLambdaPtResolution"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution } } //_______________________________________ // AntiLambda MC association - if (sigma.lambdaCandPDGCode() == -3122) { - if (sigma.lambdaMCPt() > 0) { - histos.fill(HIST("BeforeSel/MC/pTReso/h2dAntiLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution + if (sigma.lambdaPDGCode() == -3122) { + if (sigma.lambdamcpt() > 0) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dAntiLambdaPtResolution"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt()); // pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution } } //_______________________________________ // Sigma and AntiSigma MC association - if (sigma.isSigma()) { - if (sigma.sigmaMCPt() > 0) - histos.fill(HIST("BeforeSel/MC/pTReso/h2dSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution + if (sigma.isSigma0()) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dSigma0RadiusResolution"), sigma.mcpt(), sigma.radius() - sigma.mcradius()); // pT resolution + if (sigma.mcpt() > 0) + histos.fill(HIST("BeforeSel/MC/Reso/h2dSigma0PtResolution"), 1.f / sigma.mcpt(), 1.f / sigma.pt() - 1.f / sigma.mcpt()); // pT resolution } - if (sigma.isAntiSigma()) { - if (sigma.sigmaMCPt() > 0) - histos.fill(HIST("BeforeSel/MC/pTReso/h2dAntiSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution + if (sigma.isAntiSigma0()) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dASigma0RadiusResolution"), sigma.mcpt(), sigma.radius() - sigma.mcradius()); // pT resolution + if (sigma.mcpt() > 0) + histos.fill(HIST("BeforeSel/MC/Reso/h2dAntiSigma0PtResolution"), 1.f / sigma.mcpt(), 1.f / sigma.pt() - 1.f / sigma.mcpt()); // pT resolution } } // To save histograms for background analysis - template - void runBkgAnalysis(TV0Object const& sigma) + template + void runBkgAnalysis(TSigma0Object const& sigma) { // Check whether it is before or after selections static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; - bool fIsSigma = sigma.isSigma(); - bool fIsAntiSigma = sigma.isAntiSigma(); - int PhotonPDGCode = sigma.photonCandPDGCode(); - int PhotonPDGCodeMother = sigma.photonCandPDGCodeMother(); - int LambdaPDGCode = sigma.lambdaCandPDGCode(); - int LambdaPDGCodeMother = sigma.lambdaCandPDGCodeMother(); - float sigmapT = sigma.sigmapT(); - float sigmaMass = sigma.sigmaMass(); + bool fIsSigma = sigma.isSigma0(); + bool fIsAntiSigma = sigma.isAntiSigma0(); + int PhotonPDGCode = sigma.photonPDGCode(); + int PhotonPDGCodeMother = sigma.photonPDGCodeMother(); + int LambdaPDGCode = sigma.lambdaPDGCode(); + int LambdaPDGCodeMother = sigma.lambdaPDGCodeMother(); + float sigmapT = sigma.pt(); + float sigmaMass = sigma.sigma0Mass(); histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_All"), sigmapT, sigmaMass); @@ -465,35 +951,31 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters"), sigmapT, sigmaMass); } - template - void fillQAHistos(TV0Object const& sigma) + template + void fillHistos(TSigma0Object const& sigma, TCollision const& collision) { // Check whether it is before or after selections - // static std::string main_dir; - // main_dir = IsBeforeSel ? "BeforeSel" : "AfterSel"; static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; // Get V0trackCode int GammaTrkCode = retrieveV0TrackCode(sigma); int LambdaTrkCode = retrieveV0TrackCode(sigma); - float photonRZLineCut = TMath::Abs(sigma.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; + float photonRZLineCut = TMath::Abs(sigma.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.PhotonMaxDauEta))) - photonSelections.PhotonLineCutZ0; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); //_______________________________________ // Photon histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hTrackCode"), GammaTrkCode); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hV0Type"), sigma.photonV0Type()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegpT"), sigma.photonNegPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPospT"), sigma.photonPosPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCANegToPV"), sigma.photonDCANegPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCAPosToPV"), sigma.photonDCAPosPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCADau"), sigma.photonDCADau()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosTPCCR"), sigma.photonPosTPCCrossedRows()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegTPCCR"), sigma.photonNegTPCCrossedRows()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dPosTPCNSigmaEl"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dNegTPCNSigmaEl"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dPosTPCNSigmaPi"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaPi()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dNegTPCNSigmaPi"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaPi()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosTPCNSigmaEl"), sigma.photonPosTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegTPCNSigmaEl"), sigma.photonNegTPCNSigmaEl()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hpT"), sigma.photonPt()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hY"), sigma.photonY()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosEta"), sigma.photonPosEta()); @@ -505,7 +987,7 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hCosPA"), sigma.photonCosPA()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPsiPair"), sigma.photonPsiPair()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPhi"), sigma.photonPhi()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h3dMass"), sigma.sigmaCentrality(), sigma.photonPt(), sigma.photonMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h3dMass"), centrality, sigma.photonPt(), sigma.photonMass()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hMass"), sigma.photonMass()); //_______________________________________ @@ -537,14 +1019,16 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaDCAPosToPV"), sigma.lambdaDCAPosPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdapT"), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaMass"), sigma.lambdaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dLambdaMass"), sigma.sigmaCentrality(), sigma.lambdaPt(), sigma.lambdaMass()); - - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hY"), sigma.sigmaRapidity()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dPhotonRadiusVsMassSigma"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h2dpTVsOPAngle"), sigma.sigmapT(), sigma.sigmaOPAngle()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dLambdaMass"), centrality, sigma.lambdaPt(), sigma.lambdaMass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hY"), sigma.sigma0Y()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hRadius"), sigma.radius()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h2dRadiusVspT"), sigma.radius(), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hDCAPairDau"), sigma.dcadaughters()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dMass"), centrality, sigma.pt(), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dOPAngleVsMass"), sigma.opAngle(), sigma.pt(), sigma.sigma0Mass()); } else { histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_ALambdaPr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_ALambdaPi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma()); @@ -552,87 +1036,98 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdaDCAPosToPV"), sigma.lambdaDCAPosPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdapT"), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hAntiLambdaMass"), sigma.antilambdaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dAntiLambdaMass"), sigma.sigmaCentrality(), sigma.lambdaPt(), sigma.antilambdaMass()); - - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hY"), sigma.sigmaRapidity()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dPhotonRadiusVsMassSigma"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h2dpTVsOPAngle"), sigma.sigmapT(), sigma.sigmaOPAngle()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dAntiLambdaMass"), centrality, sigma.lambdaPt(), sigma.antilambdaMass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hY"), sigma.sigma0Y()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hRadius"), sigma.radius()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h2dRadiusVspT"), sigma.radius(), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hDCAPairDau"), sigma.dcadaughters()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dMass"), centrality, sigma.pt(), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dOPAngleVsMass"), sigma.opAngle(), sigma.pt(), sigma.sigma0Mass()); } //_______________________________________ // MC specific if (doprocessMonteCarlo) { - if constexpr (requires { sigma.lambdaCandPDGCode(); sigma.photonCandPDGCode(); }) { + if constexpr (requires { sigma.lambdaPDGCode(); sigma.photonPDGCode(); }) { //_______________________________________ // Gamma MC association - if (sigma.photonCandPDGCode() == 22) { + if (sigma.photonPDGCode() == 22) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hV0ToCollAssoc"), sigma.photonIsCorrectlyAssoc()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt"), sigma.photonPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hMCPt"), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hMCPt"), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPosTPCNSigmaEl"), sigma.photonPosTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hNegTPCNSigmaEl"), sigma.photonNegTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPosTPCNSigmaEl"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dNegTPCNSigmaEl"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPosTPCNSigmaPi"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaPi()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dNegTPCNSigmaPi"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaPi()); - - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt"), TMath::ACos(sigma.photonCosPA()), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt"), TMath::ACos(sigma.photonCosPA()), sigma.photonmcpt()); if (!sigma.photonIsCorrectlyAssoc()) { - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt_BadCollAssig"), sigma.photonMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt_BadCollAssig"), TMath::ACos(sigma.photonCosPA()), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt_BadCollAssig"), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt_BadCollAssig"), TMath::ACos(sigma.photonCosPA()), sigma.photonmcpt()); } } //_______________________________________ // Lambda MC association - if (sigma.lambdaCandPDGCode() == 3122) { + if (sigma.lambdaPDGCode() == 3122) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hV0ToCollAssoc"), sigma.lambdaIsCorrectlyAssoc()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hPt"), sigma.lambdaPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hMCPt"), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hMCPt"), sigma.lambdamcpt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/h3dTPCvsTOFNSigma_Pr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/h3dTPCvsTOFNSigma_Pi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.lambdaPt()); } //_______________________________________ // AntiLambda MC association - if (sigma.lambdaCandPDGCode() == -3122) { + if (sigma.lambdaPDGCode() == -3122) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hV0ToCollAssoc"), sigma.lambdaIsCorrectlyAssoc()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hPt"), sigma.lambdaPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hMCPt"), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hMCPt"), sigma.lambdamcpt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/h3dTPCvsTOFNSigma_Pr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma(), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/h3dTPCvsTOFNSigma_Pi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma(), sigma.lambdaPt()); } //_______________________________________ // Sigma0 MC association - if (sigma.isSigma()) { + if (sigma.isSigma0()) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCPt"), sigma.sigmaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsGammaMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCPt"), sigma.mcpt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsLambdaMCPt"), sigma.mcpt(), sigma.lambdamcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsPhotonMCPt"), sigma.mcpt(), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMass"), centrality, sigma.mcpt(), sigma.sigma0Mass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCProcess"), sigma.mcprocess()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hGenRadius"), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCProcessVsGenRadius"), sigma.mcprocess(), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMCProcess"), sigma.mcprocess(), sigma.mcpt(), sigma.sigma0Mass()); } //_______________________________________ // AntiSigma0 MC association - if (sigma.isAntiSigma()) { + if (sigma.isAntiSigma0()) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCPt"), sigma.sigmaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsPhotonMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCPt"), sigma.mcpt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsLambdaMCPt"), sigma.mcpt(), sigma.lambdamcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsPhotonMCPt"), sigma.mcpt(), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMass"), centrality, sigma.mcpt(), sigma.sigma0Mass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCProcess"), sigma.mcprocess()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hGenRadius"), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCProcessVsGenRadius"), sigma.mcprocess(), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMCProcess"), sigma.mcprocess(), sigma.mcpt(), sigma.sigma0Mass()); } // For background studies: @@ -641,17 +1136,17 @@ struct sigmaanalysis { //_______________________________________ // pT resolution histos - if ((mode == 0) && fillpTResoQAhistos) - getpTResolution(sigma); + if ((mode == 0) && fillResoQAhistos) + getResolution(sigma); } } } - template - void fillSelHistos(TV0Object const& sigma, int PDGRequired) + template + void fillSelHistos(TSigma0Object const& sigma, int PDGRequired) { - static constexpr std::string_view PhotonSelsLocal[] = {"NoSel", "V0Type", "DaupT", "DCADauToPV", + static constexpr std::string_view PhotonSelsLocal[] = {"NoSel", "V0Type", "DCADauToPV", "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", "PsiPair", "Phi", "Mass"}; @@ -664,7 +1159,7 @@ struct sigmaanalysis { if constexpr (selection_index >= 0 && selection_index < (int)std::size(PhotonSelsLocal)) { histos.fill(HIST("Selection/Photon/hCandidateSel"), selection_index); histos.fill(HIST("Selection/Photon/h2d") + HIST(PhotonSelsLocal[selection_index]), sigma.photonPt(), sigma.photonMass()); - histos.fill(HIST("Selection/Sigma0/h2dPhoton") + HIST(PhotonSelsLocal[selection_index]), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("Selection/Sigma0/h2dPhoton") + HIST(PhotonSelsLocal[selection_index]), sigma.pt(), sigma.sigma0Mass()); } } @@ -672,7 +1167,7 @@ struct sigmaanalysis { if constexpr (selection_index >= 0 && selection_index < (int)std::size(LambdaSelsLocal)) { histos.fill(HIST("Selection/Lambda/hCandidateSel"), selection_index); histos.fill(HIST("Selection/Lambda/h2d") + HIST(LambdaSelsLocal[selection_index]), sigma.lambdaPt(), sigma.lambdaMass()); - histos.fill(HIST("Selection/Sigma0/h2dLambda") + HIST(LambdaSelsLocal[selection_index]), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("Selection/Sigma0/h2dLambda") + HIST(LambdaSelsLocal[selection_index]), sigma.pt(), sigma.sigma0Mass()); } } } @@ -682,73 +1177,69 @@ struct sigmaanalysis { bool selectPhoton(TV0Object const& cand) { fillSelHistos<0>(cand, 22); - if (cand.photonV0Type() != Photonv0TypeSel && Photonv0TypeSel > -1) + if (cand.photonV0Type() != photonSelections.Photonv0TypeSel && photonSelections.Photonv0TypeSel > -1) return false; fillSelHistos<1>(cand, 22); - if ((cand.photonPosPt() < PhotonDauMinPt) || (cand.photonNegPt() < PhotonDauMinPt)) + if ((TMath::Abs(cand.photonDCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < photonSelections.PhotonMinDCADauToPv)) return false; fillSelHistos<2>(cand, 22); - if ((TMath::Abs(cand.photonDCAPosPV()) < PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < PhotonMinDCADauToPv)) + if (TMath::Abs(cand.photonDCADau()) > photonSelections.PhotonMaxDCAV0Dau) return false; fillSelHistos<3>(cand, 22); - if (TMath::Abs(cand.photonDCADau()) > PhotonMaxDCAV0Dau) + if ((cand.photonPosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows)) return false; fillSelHistos<4>(cand, 22); - if ((cand.photonPosTPCCrossedRows() < PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < PhotonMinTPCCrossedRows)) + if (((cand.photonPosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) return false; - fillSelHistos<5>(cand, 22); - if (((cand.photonPosTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > PhotonMaxTPCNSigmas))) + if (((cand.photonNegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) return false; - if (((cand.photonNegTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > PhotonMaxTPCNSigmas))) + fillSelHistos<5>(cand, 22); + if ((cand.photonPt() < photonSelections.PhotonMinPt) || (cand.photonPt() > photonSelections.PhotonMaxPt)) return false; fillSelHistos<6>(cand, 22); - if ((cand.photonPt() < PhotonMinPt) || (cand.photonPt() > PhotonMaxPt)) + if ((TMath::Abs(cand.photonY()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > photonSelections.PhotonMaxDauEta)) return false; fillSelHistos<7>(cand, 22); - if ((TMath::Abs(cand.photonY()) > PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > PhotonMaxDauEta)) + if ((cand.photonRadius() < photonSelections.PhotonMinRadius) || (cand.photonRadius() > photonSelections.PhotonMaxRadius)) return false; fillSelHistos<8>(cand, 22); - if ((cand.photonRadius() < PhotonMinRadius) || (cand.photonRadius() > PhotonMaxRadius)) + float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.PhotonMaxDauEta))) - photonSelections.PhotonLineCutZ0; + if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > photonSelections.PhotonMaxZ)) return false; fillSelHistos<9>(cand, 22); - float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; - if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > PhotonMaxZ)) + if (cand.photonQt() > photonSelections.PhotonMaxQt) return false; - fillSelHistos<10>(cand, 22); - if (cand.photonQt() > PhotonMaxQt) + if (TMath::Abs(cand.photonAlpha()) > photonSelections.PhotonMaxAlpha) return false; - if (TMath::Abs(cand.photonAlpha()) > PhotonMaxAlpha) + fillSelHistos<10>(cand, 22); + if (cand.photonCosPA() < photonSelections.PhotonMinV0cospa) return false; fillSelHistos<11>(cand, 22); - if (cand.photonCosPA() < PhotonMinV0cospa) + if (TMath::Abs(cand.photonPsiPair()) > photonSelections.PhotonPsiPairMax) return false; fillSelHistos<12>(cand, 22); - if (TMath::Abs(cand.photonPsiPair()) > PhotonPsiPairMax) + if ((((cand.photonPhi() > photonSelections.PhotonPhiMin1) && (cand.photonPhi() < photonSelections.PhotonPhiMax1)) || ((cand.photonPhi() > photonSelections.PhotonPhiMin2) && (cand.photonPhi() < photonSelections.PhotonPhiMax2))) && ((photonSelections.PhotonPhiMin1 != -1) && (photonSelections.PhotonPhiMax1 != -1) && (photonSelections.PhotonPhiMin2 != -1) && (photonSelections.PhotonPhiMax2 != -1))) return false; fillSelHistos<13>(cand, 22); - if ((((cand.photonPhi() > PhotonPhiMin1) && (cand.photonPhi() < PhotonPhiMax1)) || ((cand.photonPhi() > PhotonPhiMin2) && (cand.photonPhi() < PhotonPhiMax2))) && ((PhotonPhiMin1 != -1) && (PhotonPhiMax1 != -1) && (PhotonPhiMin2 != -1) && (PhotonPhiMax2 != -1))) + if (TMath::Abs(cand.photonMass()) > photonSelections.PhotonMaxMass) return false; fillSelHistos<14>(cand, 22); - if (TMath::Abs(cand.photonMass()) > PhotonMaxMass) - return false; - - fillSelHistos<15>(cand, 22); return true; } @@ -757,68 +1248,68 @@ struct sigmaanalysis { bool selectLambda(TV0Object const& cand) { fillSelHistos<0>(cand, 3122); - if ((cand.lambdaRadius() < LambdaMinv0radius) || (cand.lambdaRadius() > LambdaMaxv0radius)) + if ((cand.lambdaRadius() < lambdaSelections.LambdaMinv0radius) || (cand.lambdaRadius() > lambdaSelections.LambdaMaxv0radius)) return false; fillSelHistos<1>(cand, 3122); - if (TMath::Abs(cand.lambdaDCADau()) > LambdaMaxDCAV0Dau) + if (TMath::Abs(cand.lambdaDCADau()) > lambdaSelections.LambdaMaxDCAV0Dau) return false; fillSelHistos<2>(cand, 3122); - if ((cand.lambdaQt() < LambdaMinQt) || (cand.lambdaQt() > LambdaMaxQt)) + if ((cand.lambdaQt() < lambdaSelections.LambdaMinQt) || (cand.lambdaQt() > lambdaSelections.LambdaMaxQt)) return false; - if ((TMath::Abs(cand.lambdaAlpha()) < LambdaMinAlpha) || (TMath::Abs(cand.lambdaAlpha()) > LambdaMaxAlpha)) + if ((TMath::Abs(cand.lambdaAlpha()) < lambdaSelections.LambdaMinAlpha) || (TMath::Abs(cand.lambdaAlpha()) > lambdaSelections.LambdaMaxAlpha)) return false; fillSelHistos<3>(cand, 3122); - if (cand.lambdaCosPA() < LambdaMinv0cospa) + if (cand.lambdaCosPA() < lambdaSelections.LambdaMinv0cospa) return false; fillSelHistos<4>(cand, 3122); - if ((TMath::Abs(cand.lambdaY()) > LambdaMaxRap) || (TMath::Abs(cand.lambdaPosEta()) > LambdaMaxDauEta) || (TMath::Abs(cand.lambdaNegEta()) > LambdaMaxDauEta)) + if ((TMath::Abs(cand.lambdaY()) > lambdaSelections.LambdaMaxRap) || (TMath::Abs(cand.lambdaPosEta()) > lambdaSelections.LambdaMaxDauEta) || (TMath::Abs(cand.lambdaNegEta()) > lambdaSelections.LambdaMaxDauEta)) return false; fillSelHistos<5>(cand, 3122); - if ((cand.lambdaPosTPCCrossedRows() < LambdaMinTPCCrossedRows) || (cand.lambdaNegTPCCrossedRows() < LambdaMinTPCCrossedRows)) + if ((cand.lambdaPosTPCCrossedRows() < lambdaSelections.LambdaMinTPCCrossedRows) || (cand.lambdaNegTPCCrossedRows() < lambdaSelections.LambdaMinTPCCrossedRows)) return false; fillSelHistos<6>(cand, 3122); // check minimum number of ITS clusters + reject ITS afterburner tracks if requested bool posIsFromAfterburner = cand.lambdaPosChi2PerNcl() < 0; bool negIsFromAfterburner = cand.lambdaNegChi2PerNcl() < 0; - if (cand.lambdaPosITSCls() < LambdaMinITSclusters && (!LambdaRejectPosITSafterburner || posIsFromAfterburner)) + if (cand.lambdaPosITSCls() < lambdaSelections.LambdaMinITSclusters && (!lambdaSelections.LambdaRejectPosITSafterburner || posIsFromAfterburner)) return false; - if (cand.lambdaNegITSCls() < LambdaMinITSclusters && (!LambdaRejectNegITSafterburner || negIsFromAfterburner)) + if (cand.lambdaNegITSCls() < lambdaSelections.LambdaMinITSclusters && (!lambdaSelections.LambdaRejectNegITSafterburner || negIsFromAfterburner)) return false; fillSelHistos<7>(cand, 3122); - if (cand.lambdaLifeTime() > LambdaMaxLifeTime) + if (cand.lambdaLifeTime() > lambdaSelections.LambdaMaxLifeTime) return false; // Separating lambda and antilambda selections: fillSelHistos<8>(cand, 3122); if (cand.lambdaAlpha() > 0) { // Lambda selection // TPC Selection - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPrTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPrTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPiTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPiTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; // TOF Selection - if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.lambdaPrTOFNSigma()) > lambdaSelections.LambdaPrMaxTOFNSigmas)) return false; - if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > lambdaSelections.LambdaPiMaxTOFNSigmas)) return false; // DCA Selection fillSelHistos<9>(cand, 3122); - if ((TMath::Abs(cand.lambdaDCAPosPV()) < LambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < LambdaMinDCANegToPv)) + if ((TMath::Abs(cand.lambdaDCAPosPV()) < lambdaSelections.LambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < lambdaSelections.LambdaMinDCANegToPv)) return false; // Mass Selection fillSelHistos<10>(cand, 3122); - if (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) + if (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) > lambdaSelections.LambdaWindow) return false; fillSelHistos<11>(cand, 3122); @@ -826,25 +1317,25 @@ struct sigmaanalysis { } else { // AntiLambda selection // TPC Selection - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPiTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPiTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPrTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPrTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; // TOF Selection - if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPrTOFNSigma()) > lambdaSelections.LambdaPrMaxTOFNSigmas)) return false; - if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPiTOFNSigma()) > lambdaSelections.LambdaPiMaxTOFNSigmas)) return false; // DCA Selection fillSelHistos<9>(cand, 3122); - if ((TMath::Abs(cand.lambdaDCAPosPV()) < ALambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < ALambdaMinDCANegToPv)) + if ((TMath::Abs(cand.lambdaDCAPosPV()) < lambdaSelections.ALambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < lambdaSelections.ALambdaMinDCANegToPv)) return false; // Mass Selection fillSelHistos<10>(cand, 3122); - if (TMath::Abs(cand.antilambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) + if (TMath::Abs(cand.antilambdaMass() - o2::constants::physics::MassLambda0) > lambdaSelections.LambdaWindow) return false; fillSelHistos<11>(cand, 3122); @@ -854,85 +1345,254 @@ struct sigmaanalysis { } // Apply selections in sigma0 candidates - template - bool processSigmaCandidate(TV0Object const& cand) + template + bool processSigma0Candidate(TSigma0Object const& cand) { + // Photon specific selections + if (!selectPhoton(cand)) + return false; - // Do ML analysis - if (fUseMLSel) { - if ((cand.gammaBDTScore() == -1) || (cand.lambdaBDTScore() == -1) || (cand.antilambdaBDTScore() == -1)) { - LOGF(fatal, "ML Score is not available! Please, enable gamma and lambda selection with ML in sigmabuilder!"); - } - // Photon selection: - if (cand.gammaBDTScore() <= Gamma_MLThreshold) - return false; + // Lambda specific selections + if (!selectLambda(cand)) + return false; - // Lambda selection: - if (cand.lambdaBDTScore() <= Lambda_MLThreshold) + // Sigma0 specific selections + // Rapidity + if constexpr (requires { cand.sigma0MCY(); }) { // MC + if (TMath::Abs(cand.sigma0MCY()) > sigma0Selections.Sigma0MaxRap) return false; - - // AntiLambda selection: - if (cand.antilambdaBDTScore() <= AntiLambda_MLThreshold) + } else { // Real data + if (TMath::Abs(cand.sigma0Y()) > sigma0Selections.Sigma0MaxRap) return false; + } + + // V0Pair Radius + if (cand.radius() > sigma0Selections.Sigma0MaxRadius) + return false; + + // DCA V0Pair Daughters + if (cand.dcadaughters() > sigma0Selections.Sigma0MaxDCADau) + return false; + // Opening Angle + if (cand.opAngle() > sigma0Selections.Sigma0MaxOPAngle) + return false; + + return true; + } + + // Main analysis function + template + void analyzeRecoeSigma0s(TCollisions const& collisions, TSigma0s const& fullSigma0s) + { + // Custom grouping + std::vector> sigma0grouped(collisions.size()); + + for (const auto& sigma0 : fullSigma0s) { + sigma0grouped[sigma0.straCollisionId()].push_back(sigma0.globalIndex()); } - // Go for standard analysis - else { + // Collisions loop + for (const auto& coll : collisions) { - // Photon specific selections - if (!selectPhoton(cand)) - return false; + // Event selection + if (!IsEventAccepted(coll, true)) + continue; - // Lambda specific selections - if (!selectLambda(cand)) - return false; + // Sigma0s loop + for (size_t i = 0; i < sigma0grouped[coll.globalIndex()].size(); i++) { + auto sigma0 = fullSigma0s.rawIteratorAt(sigma0grouped[coll.globalIndex()][i]); + + // if MC + if constexpr (requires { sigma0.isSigma0(); sigma0.isAntiSigma0(); }) { + if (doMCAssociation && !(sigma0.isSigma0() || sigma0.isAntiSigma0())) + continue; + + if (selRecoFromGenerator && !sigma0.isProducedByGenerator()) + continue; + } + + // Fill histos before any selection + fillHistos<0>(sigma0, coll); + + // Select sigma0 candidates + if (!processSigma0Candidate(sigma0)) + continue; + + // Fill histos after all selections + fillHistos<1>(sigma0, coll); + } + } + } + + // Apply selections in sigma0 candidates + template + bool processPi0Candidate(TPi0Object const& cand) + { + if ((cand.photon1V0Type() != photonSelections.Photonv0TypeSel || cand.photon2V0Type() != photonSelections.Photonv0TypeSel) && photonSelections.Photonv0TypeSel > -1) + return false; + + if ((TMath::Abs(cand.photon1DCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || + (TMath::Abs(cand.photon2DCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || + (TMath::Abs(cand.photon1DCANegPV()) < photonSelections.PhotonMinDCADauToPv) || + (TMath::Abs(cand.photon2DCANegPV()) < photonSelections.PhotonMinDCADauToPv)) + return false; + + if ((TMath::Abs(cand.photon1DCADau()) > photonSelections.PhotonMaxDCAV0Dau) || (TMath::Abs(cand.photon2DCADau()) > photonSelections.PhotonMaxDCAV0Dau)) + return false; + + if ((cand.photon1PosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || + (cand.photon2PosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || + (cand.photon1NegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || + (cand.photon2NegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows)) + return false; + + if (((cand.photon1PosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon1PosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas)) || + ((cand.photon2PosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon2PosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) + return false; + + if (((cand.photon1NegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon1NegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas)) || + ((cand.photon2NegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon2NegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) + return false; + + if (((cand.photon1Pt() < photonSelections.PhotonMinPt) || + (cand.photon1Pt() > photonSelections.PhotonMaxPt)) || + ((cand.photon2Pt() < photonSelections.PhotonMinPt) || + (cand.photon2Pt() > photonSelections.PhotonMaxPt))) + return false; + + if ((TMath::Abs(cand.photon1Y()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photon1PosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photon1NegEta()) > photonSelections.PhotonMaxDauEta)) + return false; + + if ((TMath::Abs(cand.photon2Y()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photon2PosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photon2NegEta()) > photonSelections.PhotonMaxDauEta)) + return false; + + if (((cand.photon1Radius() < photonSelections.PhotonMinRadius) || (cand.photon1Radius() > photonSelections.PhotonMaxRadius)) || + ((cand.photon2Radius() < photonSelections.PhotonMinRadius) || (cand.photon2Radius() > photonSelections.PhotonMaxRadius))) + return false; + + if ((cand.photon1Qt() > photonSelections.PhotonMaxQt) || cand.photon2Qt() > photonSelections.PhotonMaxQt) + return false; + + if ((TMath::Abs(cand.photon1Alpha()) > photonSelections.PhotonMaxAlpha) || (TMath::Abs(cand.photon2Alpha()) > photonSelections.PhotonMaxAlpha)) + return false; + + if ((cand.photon1CosPA() < photonSelections.PhotonMinV0cospa) || (cand.photon2CosPA() < photonSelections.PhotonMinV0cospa)) + return false; - // Sigma0 specific selections - if (TMath::Abs(cand.sigmaRapidity()) > SigmaMaxRap) + if ((TMath::Abs(cand.photon1Mass()) > photonSelections.PhotonMaxMass) || (TMath::Abs(cand.photon2Mass()) > photonSelections.PhotonMaxMass)) + return false; + + // Pi0 specific selections + if constexpr (requires { cand.pi0MCY(); }) { // MC + if (TMath::Abs(cand.pi0MCY()) > pi0Selections.Pi0MaxRap) + return false; + } else { // DATA + if (TMath::Abs(cand.pi0Y()) > pi0Selections.Pi0MaxRap) return false; } + // V0Pair Radius + if (cand.radius() > pi0Selections.Pi0MaxRadius) + return false; + + // DCA V0Pair Daughters + if (cand.dcadaughters() > pi0Selections.Pi0MaxDCADau) + return false; + return true; } - void processMonteCarlo(V0MCSigmas const& sigmas) + // Main Pi0 QA analysis function + template + void analyzeRecoePi0s(TCollisions const& collisions, TPi0s const& fullPi0s) { - for (auto& sigma : sigmas) { // selecting Sigma0-like candidates - if (doMCAssociation && !(sigma.isSigma() || sigma.isAntiSigma())) { - continue; - } + // Custom grouping + std::vector> pi0grouped(collisions.size()); - // Fill histos before any selection - fillQAHistos<0>(sigma); + for (const auto& pi0 : fullPi0s) { + pi0grouped[pi0.straCollisionId()].push_back(pi0.globalIndex()); + } + + // Collisions loop + for (const auto& coll : collisions) { - // Select sigma0 candidates - if (!processSigmaCandidate(sigma)) + // Event selection + if (!IsEventAccepted(coll, true)) continue; - // Fill histos after all selections - fillQAHistos<1>(sigma); + // Pi0s loop + float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); + + for (size_t i = 0; i < pi0grouped[coll.globalIndex()].size(); i++) { + auto pi0 = fullPi0s.rawIteratorAt(pi0grouped[coll.globalIndex()][i]); + + // Select sigma0 candidates + if (!processPi0Candidate(pi0)) + continue; + + // If MC + if constexpr (requires { pi0.isPi0(); }) { + if (selRecoFromGenerator && !pi0.isProducedByGenerator()) + continue; + + if (pi0.isPi0()) + histos.fill(HIST("Pi0/h3dMass_MCAssociated"), centrality, pi0.mcpt(), pi0.pi0Mass()); + } + + // Fill histos after all selections + histos.fill(HIST("Pi0/hMass"), pi0.pi0Mass()); + histos.fill(HIST("Pi0/hPt"), pi0.pt()); + histos.fill(HIST("Pi0/hY"), pi0.pi0Y()); + histos.fill(HIST("Pi0/h3dMass"), centrality, pi0.pt(), pi0.pi0Mass()); + } } } - void processRealData(V0Sigmas const& sigmas) + void processRealData(soa::Join const& collisions, Sigma0s const& fullSigma0s) { - for (auto& sigma : sigmas) { // selecting Sigma0-like candidates + analyzeRecoeSigma0s(collisions, fullSigma0s); + } - // Fill histos before any selection - fillQAHistos<0>(sigma); + void processMonteCarlo(soa::Join const& collisions, MCSigma0s const& fullSigma0s) + { + analyzeRecoeSigma0s(collisions, fullSigma0s); + } - // Select sigma0 candidates - if (!processSigmaCandidate(sigma)) - continue; + // Simulated processing in Run 3 + void processGeneratedRun3(soa::Join const& mcCollisions, soa::Join const& collisions, soa::Join const& Sigma0Gens) + { + analyzeGenerated(mcCollisions, collisions, Sigma0Gens); + } - // Fill histos after all selections - fillQAHistos<1>(sigma); - } + // _____________________________________________________ + // Pi0 QA + void processPi0RealData(soa::Join const& collisions, soa::Join const& fullPi0s) + { + analyzeRecoePi0s(collisions, fullPi0s); } - PROCESS_SWITCH(sigmaanalysis, processMonteCarlo, "Do Monte-Carlo-based analysis", false); + void processPi0MonteCarlo(soa::Join const& collisions, soa::Join const& fullPi0s) + { + analyzeRecoePi0s(collisions, fullPi0s); + } + + void processPi0GeneratedRun3(soa::Join const& mcCollisions, soa::Join const& collisions, soa::Join const& Pi0Gens) + { + analyzeGenerated(mcCollisions, collisions, Pi0Gens); + } + + // _____________________________________________________ PROCESS_SWITCH(sigmaanalysis, processRealData, "Do real data analysis", true); + PROCESS_SWITCH(sigmaanalysis, processMonteCarlo, "Do Monte-Carlo-based analysis", false); + PROCESS_SWITCH(sigmaanalysis, processGeneratedRun3, "process MC generated Run 3", false); + PROCESS_SWITCH(sigmaanalysis, processPi0RealData, "Do real data analysis for pi0 QA", false); + PROCESS_SWITCH(sigmaanalysis, processPi0MonteCarlo, "Do Monte-Carlo-based analysis for pi0 QA", false); + PROCESS_SWITCH(sigmaanalysis, processPi0GeneratedRun3, "process MC generated Run 3 for pi0 QA", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx b/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx index 728d8c6675b..55962630818 100644 --- a/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx +++ b/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx @@ -246,7 +246,7 @@ struct strangenessderivedbinnedinfo { ConfigurableAxis axisOccupancy{"axisOccupancy", {VARIABLE_WIDTH, 0.0f, 1000.0f, 3000.0f, 10000.0f, 30000.0f}, "Occupancy"}; // topological variable QA axes - ConfigurableAxis axisMass{"axisV0Mass", {25, 0.45, 0.55f}, "Invariant mass (GeV/#it{c}^{2})"}; + ConfigurableAxis axisMass{"axisV0Mass", {25, -0.05f, 0.05f}, "Invariant mass (GeV/#it{c}^{2})"}; ConfigurableAxis axisPhi{"axisPhi", {36, 0.0f, constants::math::TwoPI}, "#varphi (rad)"}; ConfigurableAxis axisEta{"axisEta", {10, -1.0f, 1.0f}, "Pseudo-rapidity #eta"}; ConfigurableAxis axisRadius{"axisRadius", {10, 0.0f, 250.0f}, "Decay radius (cm)"}; @@ -805,13 +805,13 @@ struct strangenessderivedbinnedinfo { float decayRadius = encodingOpts.useSqrtEncodingForRadius ? std::sqrt(v0.v0radius()) : v0.v0radius(); if (analyseK0Short && isV0Selected(v0, collision, v0.yK0Short())) { - histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mK0Short(), pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mK0Short() - o2::constants::physics::MassK0Short, pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); } if (analyseLambda && isV0Selected(v0, collision, v0.yLambda())) { - histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mLambda(), pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mLambda() - o2::constants::physics::MassLambda0, pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); } if (analyseAntiLambda && isV0Selected(v0, collision, v0.yLambda())) { - histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mAntiLambda(), pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mAntiLambda() - o2::constants::physics::MassLambda0, pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); } } // end v0 loop } @@ -827,10 +827,10 @@ struct strangenessderivedbinnedinfo { float decayRadius = encodingOpts.useSqrtEncodingForRadius ? std::sqrt(cascade.cascradius()) : cascade.cascradius(); if (analyseXi && isCascadeSelected(cascade, collision, cascade.yXi())) { - histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), cascade.m(1), pT, cascade.phi(), cascade.eta(), 0., 0., decayRadius, centrality, occupancy); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), cascade.m(1) - o2::constants::physics::MassXiMinus, pT, cascade.phi(), cascade.eta(), 0., 0., decayRadius, centrality, occupancy); } if (analyseOmega && isCascadeSelected(cascade, collision, cascade.yOmega())) { - histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), cascade.m(2), pT, cascade.phi(), cascade.eta(), 0., 0., decayRadius, centrality, occupancy); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), cascade.m(2) - o2::constants::physics::MassOmegaMinus, pT, cascade.phi(), cascade.eta(), 0., 0., decayRadius, centrality, occupancy); } } // end cascade loop } diff --git a/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx b/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx index d91e8ae5f49..367b4e2f9b3 100644 --- a/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx +++ b/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx @@ -91,7 +91,7 @@ struct V0PtInvMassPlots { // Configurables switches for v0 selection Configurable doRapidityCut{"doRapidityCut", true, "Enable rapidity v0 selection"}; Configurable doDaughterPseudorapidityCut{"doDaughterPseudorapidityCut", true, "Enable Daughter pseudorapidity v0 selection"}; - Configurable doisITSAfterburner{"doisITSAfterburner", true, "Enable ITS Afterburner"}; + Configurable doisNotITSAfterburner{"doisNotITSAfterburner", true, "Enable Tracks do not come from Afterburner"}; Configurable doitsMinHits{"doitsMinHits", true, "Enable ITS Minimum hits"}; // Configurables switches for K0sh selection @@ -228,7 +228,6 @@ struct V0PtInvMassPlots { rPtAnalysis.add("hNK0sh", "hNK0sh", {HistType::kTH1D, {{11, 0.f, 11.f}}}); rPtAnalysis.add("hNLambda", "hNLambda", {HistType::kTH1D, {{11, 0.f, 11.f}}}); rPtAnalysis.add("hNAntilambda", "hNAntilambda", {HistType::kTH1D, {{11, 0.f, 11.f}}}); - rPtAnalysis.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); rPtAnalysis.add("hArmenterosPodolanskiPlot", "hArmenterosPodolanskiPlot", {HistType::kTH2F, {{armenterosasymAxis}, {armenterosQtAxis}}}); rPtAnalysis.add("hV0EtaDaughters", "hV0EtaDaughters", {HistType::kTH1F, {{nBins, -1.2f, 1.2f}}}); @@ -334,47 +333,47 @@ struct V0PtInvMassPlots { { rPtAnalysis.fill(HIST("hNEvents"), 0.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(1, "All"); - if (!(collision.sel8() && dosel8)) { + if (dosel8 && !collision.sel8()) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 1.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(2, "sel 8"); - if (!(doNoTimeFrameBorder && collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { + if (doNoTimeFrameBorder && collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 2.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(3, "NoTimeFrameBorder"); - if (!(doNoITSROFrameBorder && collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + if (doNoITSROFrameBorder && collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 3.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(4, "NoITSROFrameBorder"); - if (!(doIsTriggerTVX && collision.selection_bit(aod::evsel::kIsTriggerTVX))) { + if (doIsTriggerTVX && collision.selection_bit(aod::evsel::kIsTriggerTVX)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 4.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(5, "IsTriggerTVX"); - if (!(docutZVertex && std::abs(collision.posZ()) < cutZVertex)) { + if (docutZVertex && std::abs(collision.posZ()) < cutZVertex) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 5.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(6, "cutZVertex"); - if (!(doIsVertexTOFmatched && collision.selection_bit(aod::evsel::kIsVertexTOFmatched))) { + if (doIsVertexTOFmatched && !collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 6.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(7, "IsVertexTOFmatched"); - if (!(doNoSameBunchPileup && collision.selection_bit(aod::evsel::kNoSameBunchPileup))) { + if (doNoSameBunchPileup && collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 7.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(8, "NoSameBunchPileup"); - if (!(doIsVertexITSTPC && collision.selection_bit(aod::evsel::kIsVertexITSTPC))) { + if (doIsVertexITSTPC && collision.selection_bit(aod::evsel::kIsVertexITSTPC)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 8.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(9, "IsVertexITSTPC"); - if (!(doisInelGt0 && collision.isInelGt0())) { + if (doisInelGt0 && collision.isInelGt0()) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 9.5); @@ -399,7 +398,7 @@ struct V0PtInvMassPlots { } rPtAnalysis.fill(HIST("hNV0s"), 1.5); rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(2, "Dau Pseudorapidity"); - if (!doisITSAfterburner && (posDaughterTrack.isITSAfterburner() || negDaughterTrack.isITSAfterburner())) { // ITS After Burner on daughter tracks + if (doisNotITSAfterburner && (posDaughterTrack.isITSAfterburner() || negDaughterTrack.isITSAfterburner())) { // ITS After Burner on daughter tracks return false; } rPtAnalysis.fill(HIST("hNV0s"), 2.5); @@ -411,6 +410,7 @@ struct V0PtInvMassPlots { // Cut Plots rPtAnalysis.fill(HIST("hV0EtaDaughters"), v0.template posTrack_as().eta()); rPtAnalysis.fill(HIST("hV0EtaDaughters"), v0.template negTrack_as().eta()); + rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlot"), v0.alpha(), v0.qtarm()); } return true; } @@ -793,7 +793,6 @@ struct V0PtInvMassPlots { if (!acceptV0(v0)) { // V0 Selections continue; } - rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlot"), v0.alpha(), v0.qtarm()); // kzero analysis if (kzeroAnalysis == true) { if (v0mcParticle.pdgCode() == kK0Short) { // kzero matched @@ -918,7 +917,6 @@ struct V0PtInvMassPlots { if (!acceptV0(v0)) { // V0 Selection continue; } - rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlot"), v0.alpha(), v0.qtarm()); // kzero analysis if (kzeroAnalysis == true) { if (!acceptK0sh(v0)) { // K0sh Selection diff --git a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx index 0f4cbd0be70..7d875f0e1b9 100644 --- a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx +++ b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx @@ -402,7 +402,7 @@ struct ExclusiveRhoTo4Pi { HistogramRegistry histosData{"Data", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry histosCounter{"counters", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; // Configurable Event parameters - Configurable ifCheckUPCmode{"ifCheckUPCmode", false, "Enable UPC reconstruction only"}; + Configurable ifUPC{"ifUPC", 1, "Enable UPC reconstruction only"}; Configurable vZCut{"vZCut", 10., "Vertex Cut"}; Configurable fv0Cut{"fv0Cut", 50., "FV0A threshold"}; Configurable ft0aCut{"ft0aCut", 50., "FT0A threshold"}; @@ -444,8 +444,8 @@ struct ExclusiveRhoTo4Pi { void init(InitContext const&) { // QA plots: Event and Track Counter - histosCounter.add("EventsCounts_vs_runNo", "Number of Selected 4-Pion Events per Run; Run Number; Number of Events", kTH2F, {{113, 0, 113}, {12, 0, 12}}); - histosCounter.add("TracksCounts_vs_runNo", "Number of Selected Tracks per Run; Run Number; Number of Tracks", kTH2F, {{113, 0, 113}, {14, 0, 14}}); + histosCounter.add("EventsCounts_vs_runNo", "Event Counter Run by Run; Run Number; Number of Events", kTH2F, {{113, 0, 113}, {14, 0, 14}}); + histosCounter.add("TracksCounts_vs_runNo", "Track Counter Run by Run; Run Number; Number of Tracks", kTH2F, {{113, 0, 113}, {14, 0, 14}}); histosCounter.add("fourPionCounts_0c", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); histosCounter.add("fourPionCounts_0c_within_mass", "Four Pion Counts within mass range; Run Number; Events", kTH1F, {{113, 0, 113}}); histosCounter.add("fourPionCounts_0c_within_rap", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); @@ -456,18 +456,22 @@ struct ExclusiveRhoTo4Pi { histosCounter.add("fourPionCounts_n0c_selected", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); // QA plots: event selection histosData.add("UPCmode", "UPC mode; Events", kTH1F, {{5, 0, 5}}); + histosData.add("GapSide", "Gap Side;Gap Side; Events", kTH1F, {{4, 0, 4}}); + histosData.add("TrueGapSide", "True Gap Side; True Gap Side; Events", kTH1F, {{4, 0, 4}}); + histosData.add("isCBTOk", "isCBTOk; bool; Events", kTH1F, {{4, 0, 4}}); + histosData.add("isCBTHadronOk", "isCBTHadronOk; bool; Events", kTH1F, {{4, 0, 4}}); + histosData.add("isCBTZdcOk", "isCBTZdcOk; bool; Events", kTH1F, {{4, 0, 4}}); + histosData.add("isCBTHadronZdcOk", "isCBTHadronZdcOk; bool; Events", kTH1F, {{4, 0, 4}}); histosData.add("FT0A", "T0A amplitude", kTH1F, {{500, 0.0, 500.0}}); histosData.add("FT0C", "T0C amplitude", kTH1F, {{500, 0.0, 500.0}}); histosData.add("FV0A", "V0A amplitude", kTH1F, {{100, 0.0, 100}}); - histosData.add("ZDC_A", "ZDC amplitude", kTH1F, {{1000, 0.0, 15}}); - histosData.add("ZDC_C", "ZDC amplitude", kTH1F, {{1000, 0.0, 15}}); - histosData.add("FDDA", "FDD A signal; FDD A signal; Counts", kTH1F, {{500, 0.0, 500}}); - histosData.add("FDDC", "FDD C signal; FDD C signal; Counts", kTH1F, {{500, 0.0, 500}}); + histosData.add("ZDC_A", "ZDC amplitude", kTH1F, {{10000, 0.0, 10000}}); + histosData.add("ZDC_C", "ZDC amplitude", kTH1F, {{10000, 0.0, 10000}}); + histosData.add("FDDA", "FDD A signal; FDD A signal; Counts", kTH1F, {{500, 0.0, 2000}}); + histosData.add("FDDC", "FDD C signal; FDD C signal; Counts", kTH1F, {{500, 0.0, 2000}}); histosData.add("vertexX", "Vertex X; Vertex X [cm]; Counts", kTH1F, {{2000, -0.05, 0.05}}); histosData.add("vertexY", "Vertex Y; Vertex Y [cm]; Counts", kTH1F, {{2000, -0.05, 0.05}}); histosData.add("vertexZ", "Vertex Z; Vertex Z [cm]; Counts", kTH1F, {{2000, -15, 15}}); - histosData.add("GapSide", "Gap Side;Gap Side; Events", kTH1F, {{4, 0, 4}}); - histosData.add("TrueGapSide", "True Gap Side; True Gap Side; Events", kTH1F, {{4, 0, 4}}); histosData.add("occupancy", "Occupancy; Occupancy; Counts", kTH1F, {{20000, 0, 20000}}); // QA plots: tracks histosData.add("dcaXY_all", "dcaXY; dcaXY [cm]; Counts", kTH1F, {{2000, -0.1, 0.1}}); @@ -573,15 +577,24 @@ struct ExclusiveRhoTo4Pi { void processData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks) { - int runIndex = getRunNumberIndex(collision.runNumber()); - // Check if the Event is reconstructed in UPC mode - if (ifCheckUPCmode && (collision.flags() != 1)) { + if (collision.flags() != ifUPC) { return; } + // RCT flag + if (!sgSelector.isCBTHadronZdcOk(collision)) { + return; + } + + int runIndex = getRunNumberIndex(collision.runNumber()); + histosData.fill(HIST("GapSide"), collision.gapSide()); histosData.fill(HIST("TrueGapSide"), sgSelector.trueGap(collision, fv0Cut, ft0aCut, ft0cCut, zdcCut)); + histosData.fill(HIST("isCBTOk"), sgSelector.isCBTOk(collision)); + histosData.fill(HIST("isCBTHadronOk"), sgSelector.isCBTHadronOk(collision)); + histosData.fill(HIST("isCBTZdcOk"), sgSelector.isCBTZdcOk(collision)); + histosData.fill(HIST("isCBTHadronZdcOk"), sgSelector.isCBTHadronZdcOk(collision)); histosData.fill(HIST("vertexX"), collision.posX()); histosData.fill(HIST("vertexY"), collision.posY()); histosData.fill(HIST("vertexZ"), collision.posZ()); @@ -940,79 +953,74 @@ struct ExclusiveRhoTo4Pi { void processEventCounter(UDCollisions::iterator const& collision) { - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 0); - - // UPC mode - if (ifCheckUPCmode && collision.flags() != 1) { + // RCT flag + if (!sgSelector.isCBTHadronZdcOk(collision)) { return; } histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 1); - + // UPC mode + if (collision.flags() != ifUPC) { + return; + } + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 2); // vtxITSTPC if (collision.vtxITSTPC() != vtxITSTPCcut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 2); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 3); // sbp if (collision.sbp() != sbpCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 3); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 4); // itsROFb if (collision.itsROFb() != itsROFbCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 4); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 5); // tfb if (collision.tfb() != tfbCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 5); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 6); // FT0A if (collision.totalFT0AmplitudeA() > ft0aCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 6); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 7); // FT0C if (collision.totalFT0AmplitudeC() > ft0cCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 7); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 8); // FV0A if (collision.totalFV0AmplitudeA() > fv0Cut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 8); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 9); // ZDC if (collision.energyCommonZNA() > zdcCut || collision.energyCommonZNC() > zdcCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 9); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 10); // numContributors if (collision.numContrib() != numPVContrib) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 10); - + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 11); // vertexZ if (std::abs(collision.posZ()) > vZCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 11); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 12); } // End of processCounter function void processTrackCounter(soa::Filtered::iterator const& collision, UDtracks const& tracks) { int runIndex = getRunNumberIndex(collision.runNumber()); // Check if the Event is reconstructed in UPC mode - if (ifCheckUPCmode && (collision.flags() != 1)) { + if (collision.flags() != ifUPC) { return; } for (const auto& track : tracks) { @@ -1194,20 +1202,49 @@ struct ExclusiveRhoTo4Pi { return -1; // Not found } // End of getRunNumberIndex function - void setHistBinLabels() + std::string strFormat(double value, int precision = 2) { + std::ostringstream oss; + oss << std::fixed << std::setprecision(precision) << value; + return oss.str(); + } - std::string eventLabels[12] = { - "No Cuts", "UPC mode", "vtxITSTPC=1", "sbp=1", "itsROFb=1", "tfb=1", - "FT0A <= 50", "FT0C <= 50", "FV0A <= 50", "ZDC <= 0", - "n PV Contrib = 4", "V_{z} < 10cm"}; + void setHistBinLabels() + { - int numEventCuts = 12; + std::string eventLabels[13] = { + "No Cuts", + "isCBTHadronOk", + "UPC or STD", + "vtxITSTPC=" + strFormat(vtxITSTPCcut, 0), + "sbp=" + strFormat(sbpCut, 0), + "itsROFb=" + strFormat(itsROFbCut, 0), + "tfb=" + strFormat(tfbCut, 0), + "FT0A<=" + strFormat(fv0Cut), + "FT0C<=" + strFormat(ft0cCut), + "FV0A<=" + strFormat(ft0aCut), + "ZDC", + "n PV Contrib = 4", + "V_{z} < " + strFormat(vZCut) + " cm"}; + + int numEventCuts = 13; std::string trackLabels[14] = { - "No Cuts", "isPVContributor", "pT > 0.15 GeV/c", "|#eta| < 0.9", "DCA Z < 2 cm", - "DCA XY cut", "hasITS", "hasTPC", "itsChi2NCl < 36", "tpcChi2NCl < 4", - "tpcNClsFindable < 70", "#pi tracks", "#pi^{+} tracks", "#pi^{-} tracks"}; + "No Cuts", + "isPVContributor", + "pT>" + strFormat(pTcut) + " GeV/c", + "|#eta|<" + strFormat(etaCut), + "DCA Z<" + strFormat(dcaZcut) + " cm", + "DCA XY cut", + "hasITS", + "hasTPC", + "itsChi2NCl<" + strFormat(itsChi2NClsCut), + "tpcChi2NCl<" + strFormat(tpcChi2NClsCut), + "tpcNClsFindable>" + strFormat(tpcNClsFindableCut), + "#pi tracks", + "#pi^{+} tracks", + "#pi^{-} tracks"}; + int numTrackCuts = 14; auto h1 = histosCounter.get(HIST("EventsCounts_vs_runNo")); @@ -1218,6 +1255,8 @@ struct ExclusiveRhoTo4Pi { auto h6 = histosCounter.get(HIST("fourPionCounts_n0c")); auto h7 = histosCounter.get(HIST("fourPionCounts_n0c_within_rap")); auto h8 = histosCounter.get(HIST("fourPionCounts_n0c_selected")); + auto h9 = histosCounter.get(HIST("fourPionCounts_0c_within_mass")); + auto h10 = histosCounter.get(HIST("fourPionCounts_n0c_within_mass")); for (int i = 0; i < numRunNums; ++i) { h1->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); @@ -1228,6 +1267,8 @@ struct ExclusiveRhoTo4Pi { h6->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); h7->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); h8->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h9->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h10->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); } for (int i = 0; i < numEventCuts; ++i) { h1->GetYaxis()->SetBinLabel(i + 1, eventLabels[i].c_str()); diff --git a/PWGUD/Tasks/flowCumulantsUpc.cxx b/PWGUD/Tasks/flowCumulantsUpc.cxx index 155a398cd44..5e2d64b6d94 100644 --- a/PWGUD/Tasks/flowCumulantsUpc.cxx +++ b/PWGUD/Tasks/flowCumulantsUpc.cxx @@ -14,42 +14,44 @@ /// \since Mar/2025 /// \brief jira: , task to measure flow observables with cumulant method -#include -#include -#include -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" +#include "FlowContainer.h" +#include "GFW.h" +#include "GFWCumulant.h" +#include "GFWPowerArray.h" +#include "GFWWeights.h" -#include "Common/DataModel/EventSelection.h" +#include "PWGUD/Core/SGSelector.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/SGSelector.h" -#include "TVector3.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include -#include "GFWPowerArray.h" -#include "GFW.h" -#include "GFWCumulant.h" -#include "GFWWeights.h" -#include "FlowContainer.h" #include "TList.h" +#include "TVector3.h" +#include +#include #include #include -#include -#include + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -122,9 +124,6 @@ struct FlowCumulantsUpc { Configurable cfgCutZDC{"cfgCutZDC", 10., "ZDC threshold"}; Configurable cfgGapSideSelection{"cfgGapSideSelection", 2, "gap selection"}; - // Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex) && (aod::cent::centFT0C > cfgCentFT0CMin) && (aod::cent::centFT0C < cfgCentFT0CMax); - // Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); - // Corrections TH1D* mEfficiency = nullptr; GFWWeights* mAcceptance = nullptr; @@ -140,12 +139,17 @@ struct FlowCumulantsUpc { OutputObj fFC{FlowContainer("FlowContainer")}; OutputObj fWeights{GFWWeights("weights")}; HistogramRegistry registry{"registry"}; + OutputObj fFCMc{FlowContainer("FlowContainerMC")}; + OutputObj fWeightsMc{GFWWeights("weightsMC")}; // define global variables GFW* fGFW = new GFW(); + GFW* fGFWMC = new GFW(); std::vector corrconfigs; + std::vector corrconfigsmc; TAxis* fPtAxis; TRandom3* fRndm = new TRandom3(0); + TRandom3* fRndmMc = new TRandom3(0); enum CentEstimators { kCentFT0C = 0, kCentFT0CVariant1, @@ -161,8 +165,6 @@ struct FlowCumulantsUpc { ctpRateFetcher mRateFetcher; TH2* gCurrentHadronicRate; - // using AodCollisions = soa::Filtered>; - // using AodTracks = soa::Filtered>; // using UdTracks = soa::Join; using UdTracksFull = soa::Join; @@ -265,6 +267,20 @@ struct FlowCumulantsUpc { registry.add("hDCAxy", "DCAxy after cuts; DCAxy (cm); Pt", {HistType::kTH2D, {{200, -0.5, 0.5}, {200, 0, 5}}}); registry.add("hTrackCorrection2d", "Correlation table for number of tracks table; uncorrected track; corrected track", {HistType::kTH2D, {axisNch, axisNch}}); + registry.add("hPhiMC", "#phi distribution", {HistType::kTH1D, {axisPhi}}); + registry.add("hPhiWeightedMC", "corrected #phi distribution", {HistType::kTH1D, {axisPhi}}); + registry.add("hEtaMC", "#eta distribution", {HistType::kTH1D, {axisEta}}); + registry.add("hPtMC", "p_{T} distribution before cut", {HistType::kTH1D, {axisPtHist}}); + registry.add("hPtRefMC", "p_{T} distribution after cut", {HistType::kTH1D, {axisPtHist}}); + registry.add("hChi2prTPCclsMC", "#chi^{2}/cluster for the TPC track segment", {HistType::kTH1D, {{100, 0., 5.}}}); + registry.add("hChi2prITSclsMC", "#chi^{2}/cluster for the ITS track", {HistType::kTH1D, {{100, 0., 50.}}}); + registry.add("hnTPCCluMC", "Number of found TPC clusters", {HistType::kTH1D, {{100, 40, 180}}}); + registry.add("hnITSCluMC", "Number of found ITS clusters", {HistType::kTH1D, {{100, 0, 20}}}); + registry.add("hnTPCCrossedRowMC", "Number of crossed TPC Rows", {HistType::kTH1D, {{100, 40, 180}}}); + registry.add("hDCAzMC", "DCAz after cuts; DCAz (cm); Pt", {HistType::kTH2D, {{200, -0.5, 0.5}, {200, 0, 5}}}); + registry.add("hDCAxyMC", "DCAxy after cuts; DCAxy (cm); Pt", {HistType::kTH2D, {{200, -0.5, 0.5}, {200, 0, 5}}}); + registry.add("hTrackCorrection2dMC", "Correlation table for number of tracks table; uncorrected track; corrected track", {HistType::kTH2D, {axisNch, axisNch}}); + o2::framework::AxisSpec axis = axisPt; int nPtBins = axis.binEdges.size() - 1; double* ptBins = &(axis.binEdges)[0]; @@ -273,6 +289,8 @@ struct FlowCumulantsUpc { if (cfgOutputNUAWeights) { fWeights->setPtBins(nPtBins, ptBins); fWeights->init(true, false); + fWeightsMc->setPtBins(nPtBins, ptBins); + fWeightsMc->init(true, false); } // add in FlowContainer to Get boostrap sample automatically @@ -335,6 +353,9 @@ struct FlowCumulantsUpc { fFC->SetName("FlowContainer"); fFC->SetXAxis(fPtAxis); fFC->Initialize(oba, axisIndependent, cfgNbootstrap); + fFCMc->SetName("FlowContainerMC"); + fFCMc->SetXAxis(fPtAxis); + fFCMc->Initialize(oba, axisIndependent, cfgNbootstrap); delete oba; // eta region @@ -365,6 +386,33 @@ struct FlowCumulantsUpc { fGFW->AddRegion("olN10", -0.8, -0.5, 1 + fPtAxis->GetNbins(), 4); fGFW->AddRegion("olfull", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 4); + fGFWMC->AddRegion("full", -0.8, 0.8, 1, 1); + fGFWMC->AddRegion("refN00", -0.8, 0., 1, 1); // gap0 negative region + fGFWMC->AddRegion("refP00", 0., 0.8, 1, 1); // gap0 positve region + fGFWMC->AddRegion("refN02", -0.8, -0.1, 1, 1); // gap2 negative region + fGFWMC->AddRegion("refP02", 0.1, 0.8, 1, 1); // gap2 positve region + fGFWMC->AddRegion("refN04", -0.8, -0.2, 1, 1); // gap4 negative region + fGFWMC->AddRegion("refP04", 0.2, 0.8, 1, 1); // gap4 positve region + fGFWMC->AddRegion("refN06", -0.8, -0.3, 1, 1); // gap6 negative region + fGFWMC->AddRegion("refP06", 0.3, 0.8, 1, 1); // gap6 positve region + fGFWMC->AddRegion("refN08", -0.8, -0.4, 1, 1); + fGFWMC->AddRegion("refP08", 0.4, 0.8, 1, 1); + fGFWMC->AddRegion("refN10", -0.8, -0.5, 1, 1); + fGFWMC->AddRegion("refP10", 0.5, 0.8, 1, 1); + fGFWMC->AddRegion("refN12", -0.8, -0.6, 1, 1); + fGFWMC->AddRegion("refP12", 0.6, 0.8, 1, 1); + fGFWMC->AddRegion("refN14", -0.8, -0.7, 1, 1); + fGFWMC->AddRegion("refP14", 0.7, 0.8, 1, 1); + fGFWMC->AddRegion("refN", -0.8, -0.4, 1, 1); + fGFWMC->AddRegion("refP", 0.4, 0.8, 1, 1); + fGFWMC->AddRegion("refM", -0.4, 0.4, 1, 1); + fGFWMC->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); + fGFWMC->AddRegion("poiN10", -0.8, -0.5, 1 + fPtAxis->GetNbins(), 2); + fGFWMC->AddRegion("poifull", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 2); + fGFWMC->AddRegion("olN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 4); + fGFWMC->AddRegion("olN10", -0.8, -0.5, 1 + fPtAxis->GetNbins(), 4); + fGFWMC->AddRegion("olfull", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 4); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {3 -3}", "ChFull32", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 -4}", "ChFull42", kFALSE)); @@ -406,6 +454,47 @@ struct FlowCumulantsUpc { corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4 2} refP10 {-4 -2}", "Ch10Gap4242", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {2 2} refP10 {-2 -2}", "Ch10Gap24", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN10 refN10 | olN10 {2 2} refP10 {-2 -2}", "Ch10Gap24", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {3 -3}", "ChFull32", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {4 -4}", "ChFull42", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {2 2 -2 -2}", "ChFull24", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {2 2 2 -2 -2 -2}", "ChFull26", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {2} refP04 {-2}", "Ch04Gap22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN06 {2} refP06 {-2}", "Ch06Gap22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ch08Gap22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {2} refP10 {-2}", "Ch10Gap22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN12 {2} refP12 {-2}", "Ch12Gap22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {3} refP04 {-3}", "Ch04Gap32", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN06 {3} refP06 {-3}", "Ch06Gap32", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN08 {3} refP08 {-3}", "Ch08Gap32", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {3} refP10 {-3}", "Ch10Gap32", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN12 {3} refP12 {-3}", "Ch12Gap32", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {4} refP04 {-4}", "Ch04Gap42", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN06 {4} refP06 {-4}", "Ch06Gap42", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN08 {4} refP08 {-4}", "Ch08Gap42", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {4} refP10 {-4}", "Ch10Gap42", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN12 {4} refP12 {-4}", "Ch12Gap42", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN {2} refP {-2}", "ChGap22", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poifull full | olfull {2 -2}", "ChFull22", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poifull full | olfull {2 2 -2 -2}", "ChFull24", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poifull full | olfull {2 2 2 -2 -2 -2}", "ChFull26", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poiN10 refN10 | olN10 {2} refP10 {-2}", "Ch10Gap22", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poiN10 refN10 | olN10 {3} refP10 {-3}", "Ch10Gap32", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poiN10 refN10 | olN10 {4} refP10 {-4}", "Ch10Gap42", kTRUE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {4 -2 -2}", "ChFull422", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {-2 -2} refP04 {4}", "Ch04GapA422", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {4} refP04 {-2 -2}", "Ch04GapB422", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {-2 -2} refP10 {4}", "Ch10GapA422", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {4} refP10 {-2 -2}", "Ch10GapB422", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {3 2 -3 -2}", "ChFull3232", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("full {4 2 -4 -2}", "ChFull4242", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {3 2} refP04 {-3 -2}", "Ch04Gap3232", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {4 2} refP04 {-4 -2}", "Ch04Gap4242", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN04 {2 2} refP04 {-2 -2}", "Ch04Gap24", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {3 2} refP10 {-3 -2}", "Ch10Gap3232", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {4 2} refP10 {-4 -2}", "Ch10Gap4242", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("refN10 {2 2} refP10 {-2 -2}", "Ch10Gap24", kFALSE)); + corrconfigsmc.push_back(fGFWMC->GetCorrelatorConfig("poiN10 refN10 | olN10 {2 2} refP10 {-2 -2}", "Ch10Gap24", kTRUE)); if (!userDefineGFWCorr.empty() && !userDefineGFWName.empty()) { LOGF(info, "User adding GFW CorrelatorConfig:"); // attentaion: here we follow the index of cfgUserDefineGFWCorr @@ -489,6 +578,51 @@ struct FlowCumulantsUpc { return; } + template + void fillProfileMC(const GFW::CorrConfig& corrconf, const ConstStr& tarName, const double& cent) + { + double dnx, val; + dnx = fGFWMC->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) { + return; + } + if (!corrconf.pTDif) { + val = fGFWMC->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (std::fabs(val) < 1) { + registry.fill(tarName, cent, val, dnx); + } + return; + } + return; + } + + void fillFCMC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) + { + double dnx, val; + dnx = fGFWMC->Calculate(corrconf, 0, kTRUE).real(); + if (!corrconf.pTDif) { + if (dnx == 0) { + return; + } + val = fGFWMC->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (std::fabs(val) < 1) { + fFCMc->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + } + return; + } + for (auto i = 1; i <= fPtAxis->GetNbins(); i++) { + dnx = fGFWMC->Calculate(corrconf, i - 1, kTRUE).real(); + if (dnx == 0) { + continue; + } + val = fGFWMC->Calculate(corrconf, i - 1, kFALSE).real() / dnx; + if (std::fabs(val) < 1) { + fFCMc->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + } + } + return; + } + void loadCorrections(uint64_t timestamp, int runNumber) { if (correctionsLoaded) { @@ -616,7 +750,8 @@ struct FlowCumulantsUpc { } // V0A T0A 5 sigma cut - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) { + constexpr int kSigmaCut = 5; + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > kSigmaCut * fT0AV0ASigma->Eval(collision.multFT0A()))) { return 0; } if (cfgEvSelV0AT0ACut) { @@ -657,7 +792,8 @@ struct FlowCumulantsUpc { if (!((multNTracksPV < fMultPVCutLow->Eval(centrality)) || (multNTracksPV > fMultPVCutHigh->Eval(centrality)) || (multTrk < fMultCutLow->Eval(centrality)) || (multTrk > fMultCutHigh->Eval(centrality)))) { registry.fill(HIST("hEventCountTentative"), 8.5); } - if (!(std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) { + constexpr int kSigmaCut = 5; + if (!(std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > kSigmaCut * fT0AV0ASigma->Eval(collision.multFT0A()))) { registry.fill(HIST("hEventCountTentative"), 9.5); } } @@ -669,7 +805,8 @@ struct FlowCumulantsUpc { if (!track.isPVContributor()) { return false; } - if (!(std::fabs(track.dcaZ()) < 2.)) { + constexpr float kDcazCut = 2.0; + if (!(std::fabs(track.dcaZ()) < kDcazCut)) { return false; } double dcaLimit = 0.0105 + 0.035 / std::pow(track.pt(), 1.1); @@ -677,15 +814,6 @@ struct FlowCumulantsUpc { return false; } return true; - - // if (cfgCutDCAzPtDepEnabled && (std::fabs(track.dcaZ()) > (0.004f + 0.013f / track.pt()))) - // return false; - - // if (cfgTrkSelSwitch) { - // return myTrackSel.IsSelected(track); - // } else { - // return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.itsNCls() >= cfgCutITSclu)); - // } } void initHadronicRate(aod::BCsWithTimestamps::iterator const& bc) @@ -705,29 +833,13 @@ struct FlowCumulantsUpc { gCurrentHadronicRate = gHadronicRate[mRunNumber]; } - // void process(AodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, AodTracks const& tracks) void process(UDCollisionsFull::iterator const& collision, UdTracksFull const& tracks) { - - // Runnumber loading test - // accept only selected run numbers - // int run = collision.runNumber(); - - // extract bc pattern from CCDB for data or anchored MC only - // if (run != lastRun && run >= 500000) { - // LOGF(info, "Updating bcPattern %d ...", run); - // auto tss = ccdb->getRunDuration(run); - // auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", tss.first); - // bcPatternB = grplhcif->getBunchFilling().getBCPattern(); - // lastRun = run; - // LOGF(info, "done!"); - // } - - // auto bcnum = collision.globalBC(); - registry.fill(HIST("hEventCount"), 0.5); int gapSide = collision.gapSide(); - if (gapSide < 0 || gapSide > 2) { + constexpr int kGapSideSelection = 0; + constexpr int kGapSideOppositeSelection = 2; + if (gapSide < kGapSideSelection || gapSide > kGapSideOppositeSelection) { return; } @@ -736,84 +848,14 @@ struct FlowCumulantsUpc { if (gapSide == cfgGapSideSelection) { return; } - - // if (!cfgUseSmallMemory && tracks.size() >= 1) { - // registry.fill(HIST("BeforeSel8_globalTracks_centT0C"), collision.centFT0C(), tracks.size()); - // } - // if (!collision.sel8()) - // return; - // if (tracks.size() < 1) - // return; registry.fill(HIST("hEventCount"), 1.5); - // auto bc = collision.bc_as(); - // int currentRunNumber = bc.runNumber(); - // for (const auto& ExcludedRun : cfgRunRemoveList.value) { - // if (currentRunNumber == ExcludedRun) { - // return; - // } - // } - // registry.fill(HIST("hEventCount"), 2.5); - // if (!cfgUseSmallMemory) { - // registry.fill(HIST("BeforeCut_globalTracks_centT0C"), collision.centFT0C(), tracks.size()); - // registry.fill(HIST("BeforeCut_PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV()); - // registry.fill(HIST("BeforeCut_globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); - // registry.fill(HIST("BeforeCut_globalTracks_multT0A"), collision.multFT0A(), tracks.size()); - // registry.fill(HIST("BeforeCut_globalTracks_multV0A"), collision.multFV0A(), tracks.size()); - // registry.fill(HIST("BeforeCut_multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); - // registry.fill(HIST("BeforeCut_multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); - // } float cent = 100; - // switch (cfgCentEstimator) { - // case kCentFT0C: - // cent = collision.centFT0C(); - // break; - // case kCentFT0CVariant1: - // cent = collision.centFT0CVariant1(); - // break; - // case kCentFT0M: - // cent = collision.centFT0M(); - // break; - // case kCentFV0A: - // cent = collision.centFV0A(); - // break; - // default: - // cent = collision.centFT0C(); - // } - // if (cfgUseTentativeEventCounter) - // eventCounterQA(collision, tracks.size(), cent); - // if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent)) - // return; - // registry.fill(HIST("hEventCount"), 3.5); float lRandom = fRndm->Rndm(); float vtxz = collision.posZ(); registry.fill(HIST("hVtxZ"), vtxz); registry.fill(HIST("hMult"), tracks.size()); registry.fill(HIST("hCent"), cent); fGFW->Clear(); - // if (cfgGetInteractionRate) { - // initHadronicRate(bc); - // double hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), mRunNumber, "ZNC hadronic") * 1.e-3; // - // double seconds = bc.timestamp() * 1.e-3 - mMinSeconds; - // if (cfgUseInteractionRateCut && (hadronicRate < cfgCutMinIR || hadronicRate > cfgCutMaxIR)) // cut on hadronic rate - // return; - // gCurrentHadronicRate->Fill(seconds, hadronicRate); - // } - // loadCorrections(bc.timestamp(), currentRunNumber); - // registry.fill(HIST("hEventCount"), 4.5); - - // // fill event QA - // if (!cfgUseSmallMemory) { - // registry.fill(HIST("globalTracks_centT0C"), collision.centFT0C(), tracks.size()); - // registry.fill(HIST("PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV()); - // registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); - // registry.fill(HIST("globalTracks_multT0A"), collision.multFT0A(), tracks.size()); - // registry.fill(HIST("globalTracks_multV0A"), collision.multFV0A(), tracks.size()); - // registry.fill(HIST("multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); - // registry.fill(HIST("multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); - // registry.fill(HIST("centFT0CVar_centFT0C"), collision.centFT0C(), collision.centFT0CVariant1()); - // registry.fill(HIST("centFT0M_centFT0C"), collision.centFT0C(), collision.centFT0M()); - // registry.fill(HIST("centFV0A_centFT0C"), collision.centFT0C(), collision.centFV0A()); - // } // // track weights float weff = 1, wacc = 1; @@ -850,11 +892,6 @@ struct FlowCumulantsUpc { registry.fill(HIST("hPhiWeighted"), phi, wacc); registry.fill(HIST("hEta"), eta); registry.fill(HIST("hPtRef"), pt); - // registry.fill(HIST("hChi2prTPCcls"), track.tpcChi2NCl()); - // registry.fill(HIST("hChi2prITScls"), track.itsChi2NCl()); - // registry.fill(HIST("hnTPCClu"), track.tpcNClsFound()); - // registry.fill(HIST("hnITSClu"), track.itsNCls()); - // registry.fill(HIST("hnTPCCrossedRow"), track.tpcNClsCrossedRows()); registry.fill(HIST("hDCAz"), track.dcaZ(), track.pt()); registry.fill(HIST("hDCAxy"), track.dcaXY(), track.pt()); nTracksCorrected += weff; @@ -876,6 +913,91 @@ struct FlowCumulantsUpc { fillFC(corrconfigs.at(l_ind), independent, lRandom); } } + PROCESS_SWITCH(FlowCumulantsUpc, process, "process", true); + + //----------------------------------------------------------------------------------------------------------------------- + void processSim(aod::UDMcCollision const& mcCollision, aod::UDMcParticles const& mcParticles) + { + registry.fill(HIST("eventCounterMC"), 0.5); + + registry.fill(HIST("hEventCount"), 1.5); + float cent = 100; + float vtxz = mcCollision.posZ(); + registry.fill(HIST("hVtxZMC"), vtxz); + registry.fill(HIST("hMultMC"), mcParticles.size()); + registry.fill(HIST("hCentMC"), cent); + + auto massPion = o2::constants::physics::MassPionCharged; + registry.fill(HIST("numberOfTracksMC"), mcParticles.size()); + // LOGF(info, "New event! mcParticles.size() = %d", mcParticles.size()); + + float lRandomMc = fRndmMc->Rndm(); + fGFWMC->Clear(); + + // // track weights + float weff = 1, wacc = 1; + double nTracksCorrected = 0; + float independent = cent; + if (cfgUseNch) { + independent = static_cast(mcParticles.size()); + } + + for (const auto& mcParticle : mcParticles) { + if (!mcParticle.isPhysicalPrimary()) + continue; + std::array momentum = {mcParticle.px(), mcParticle.py(), mcParticle.pz()}; + double energy = std::sqrt(momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2] + massPion * massPion); + ROOT::Math::LorentzVector> protoMC(momentum[0], momentum[1], momentum[2], energy); + constexpr double kEtaCut = 0.8; + constexpr double kPtCut = 0.1; + if (!(std::fabs(protoMC.Eta()) < kEtaCut && protoMC.Pt() > kPtCut)) { + continue; + } + // auto momentum = std::array{mcParticle.px(), mcParticle.py(), mcParticle.pz()}; + double pt = RecoDecay::pt(momentum); + double phi = RecoDecay::phi(momentum); + double eta = RecoDecay::eta(momentum); + bool withinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range + bool withinPtRef = (cfgCutPtRefMin < pt) && (pt < cfgCutPtRefMax); // within RF pT range + if (cfgOutputNUAWeights) { + if (cfgOutputNUAWeightsRefPt) { + if (withinPtRef) { + fWeightsMc->fill(phi, eta, vtxz, pt, cent, 0); + } + } else { + fWeightsMc->fill(phi, eta, vtxz, pt, cent, 0); + } + } + if (!setCurrentParticleWeights(weff, wacc, phi, eta, pt, vtxz)) { + continue; + } + if (withinPtRef) { + registry.fill(HIST("hPhiMC"), phi); + registry.fill(HIST("hPhiWeightedMC"), phi, wacc); + registry.fill(HIST("hEtaMC"), eta); + registry.fill(HIST("hPtRefMC"), pt); + // registry.fill(HIST("hDCAzMC"), track.dcaZ(), track.pt()); + // registry.fill(HIST("hDCAxyMC"), track.dcaXY(), track.pt()); + nTracksCorrected += weff; + } + if (withinPtRef) { + fGFWMC->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 1); + } + if (withinPtPOI) { + fGFWMC->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 2); + } + if (withinPtPOI && withinPtRef) { + fGFWMC->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 4); + } + } + registry.fill(HIST("hTrackCorrection2dMC"), mcParticles.size(), nTracksCorrected); + + // Filling Flow Container + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + fillFCMC(corrconfigs.at(l_ind), independent, lRandomMc); + } + PROCESS_SWITCH(FlowCumulantsUpc, processSim, "processSim", false); + } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx index d20a78429dd..d0b69e05aaf 100644 --- a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx +++ b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx @@ -8,33 +8,36 @@ // 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. -/// -/// \brief -/// \author Josué Martínez García, josuem@cern.ch -/// \file upcPhotonuclearAnalysisJMG.cxx -#include +/// \file upcPhotonuclearAnalysisJMG.cxx +/// \brief Task for photonuclear UPC analysis for azimuthal correlation: selection, histograms and observables. +/// \author Josué Martínez García -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/StepTHn.h" -#include "CommonConstants/MathConstants.h" -#include +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGUD/Core/UPCPairCuts.h" +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "PWGUD/DataModel/UDTables.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGCF/Core/CorrelationContainer.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/MathConstants.h" #include "DataFormatsParameters/GRPObject.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/UPCPairCuts.h" -#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include + +#include +#include using namespace o2; using namespace o2::framework; @@ -47,21 +50,21 @@ namespace tree DECLARE_SOA_COLUMN(PtSideA, ptSideA, std::vector); DECLARE_SOA_COLUMN(RapSideA, rapSideA, std::vector); DECLARE_SOA_COLUMN(PhiSideA, phiSideA, std::vector); -DECLARE_SOA_COLUMN(TPCSignalSideA, tpcSignalSideA, std::vector); -DECLARE_SOA_COLUMN(TOFSignalSideA, tofSignalSideA, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaPiSideA, tpcNSigmaPiSideA, std::vector); -DECLARE_SOA_COLUMN(TOFNSigmaPiSideA, tofNSigmaPiSideA, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaKaSideA, tpcNSigmaKaSideA, std::vector); -DECLARE_SOA_COLUMN(TOFNSigmaKaSideA, tofNSigmaKaSideA, std::vector); +DECLARE_SOA_COLUMN(TpcSignalSideA, tpcSignalSideA, std::vector); +DECLARE_SOA_COLUMN(TofSignalSideA, tofSignalSideA, std::vector); +DECLARE_SOA_COLUMN(TpcNSigmaPiSideA, tpcNSigmaPiSideA, std::vector); +DECLARE_SOA_COLUMN(TofNSigmaPiSideA, tofNSigmaPiSideA, std::vector); +DECLARE_SOA_COLUMN(TpcNSigmaKaSideA, tpcNSigmaKaSideA, std::vector); +DECLARE_SOA_COLUMN(TofNSigmaKaSideA, tofNSigmaKaSideA, std::vector); DECLARE_SOA_COLUMN(PtSideC, ptSideC, std::vector); DECLARE_SOA_COLUMN(RapSideC, rapSideC, std::vector); DECLARE_SOA_COLUMN(PhiSideC, phiSideC, std::vector); -DECLARE_SOA_COLUMN(TPCSignalSideC, tpcSignalSideC, std::vector); -DECLARE_SOA_COLUMN(TOFSignalSideC, tofSignalSideC, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaPiSideC, tpcNSigmaPiSideC, std::vector); -DECLARE_SOA_COLUMN(TOFNSigmaPiSideC, tofNSigmaPiSideC, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaKaSideC, tpcNSigmaKaSideC, std::vector); -DECLARE_SOA_COLUMN(TOFNSigmaKaSideC, tofNSigmaKaSideC, std::vector); +DECLARE_SOA_COLUMN(TpcSignalSideC, tpcSignalSideC, std::vector); +DECLARE_SOA_COLUMN(TofSignalSideC, tofSignalSideC, std::vector); +DECLARE_SOA_COLUMN(TpcNSigmaPiSideC, tpcNSigmaPiSideC, std::vector); +DECLARE_SOA_COLUMN(TofNSigmaPiSideC, tofNSigmaPiSideC, std::vector); +DECLARE_SOA_COLUMN(TpcNSigmaKaSideC, tpcNSigmaKaSideC, std::vector); +DECLARE_SOA_COLUMN(TofNSigmaKaSideC, tofNSigmaKaSideC, std::vector); DECLARE_SOA_COLUMN(NchSideA, nchSideA, int); DECLARE_SOA_COLUMN(MultiplicitySideA, multiplicitySideA, int); DECLARE_SOA_COLUMN(NchSideC, nchSideC, int); @@ -71,21 +74,21 @@ DECLARE_SOA_TABLE(TREE, "AOD", "Tree", tree::PtSideA, tree::RapSideA, tree::PhiSideA, - tree::TPCSignalSideA, - tree::TOFSignalSideA, - tree::TPCNSigmaPiSideA, - tree::TOFNSigmaPiSideA, - tree::TPCNSigmaKaSideA, - tree::TOFNSigmaKaSideA, + tree::TpcSignalSideA, + tree::TofSignalSideA, + tree::TpcNSigmaPiSideA, + tree::TofNSigmaPiSideA, + tree::TpcNSigmaKaSideA, + tree::TofNSigmaKaSideA, tree::PtSideC, tree::RapSideC, tree::PhiSideC, - tree::TPCSignalSideC, - tree::TOFSignalSideC, - tree::TPCNSigmaPiSideC, - tree::TOFNSigmaPiSideC, - tree::TPCNSigmaKaSideC, - tree::TOFNSigmaKaSideC, + tree::TpcSignalSideC, + tree::TofSignalSideC, + tree::TpcNSigmaPiSideC, + tree::TofNSigmaPiSideC, + tree::TpcNSigmaKaSideC, + tree::TofNSigmaKaSideC, tree::NchSideA, tree::MultiplicitySideA, tree::NchSideC, @@ -93,8 +96,9 @@ DECLARE_SOA_TABLE(TREE, "AOD", "Tree", } // namespace o2::aod static constexpr float CFGPairCutDefaults[1][5] = {{-1, -1, -1, -1, -1}}; +constexpr float kThreeHalfPi = 1.5f * PI; -struct upcPhotonuclearAnalysisJMG { +struct UpcPhotonuclearAnalysisJMG { Produces tree; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -106,20 +110,20 @@ struct upcPhotonuclearAnalysisJMG { Configurable myTimeZNACut{"myTimeZNACut", 2., {"My collision cut"}}; Configurable myTimeZNCCut{"myTimeZNCCut", 2., {"My collision cut"}}; // Declare configurables on side A gap - Configurable cutAGapMyEnergyZNAMax{"cutAGapMyEnergyZNAMax", 0., {"My collision cut. A Gap"}}; + Configurable cutGapAMyEnergyZNA{"cutGapAMyEnergyZNA", 0., {"My collision cut. A Gap"}}; // Configurable cutAGapMyAmplitudeFT0AMax{"cutAGapMyAmplitudeFT0AMax", 200., {"My collision cut. A Gap"}}; - Configurable cutAGapMyEnergyZNCMin{"cutAGapMyEnergyZNCMin", 1., {"My collision cut. A Gap"}}; + Configurable cutGapAMyEnergyZNC{"cutGapAMyEnergyZNC", 1., {"My collision cut. A Gap"}}; // Configurable cutAGapMyAmplitudeFT0CMin{"cutAGapMyAmplitudeFT0CMin", 0., {"My collision cut. A Gap"}}; // Declare configurables on side C gap - Configurable cutCGapMyEnergyZNAMin{"cutCGapMyEnergyZNAMin", 1., {"My collision cut. C Gap"}}; + Configurable cutGapCMyEnergyZNA{"cutGapCMyEnergyZNA", 1., {"My collision cut. C Gap"}}; // Configurable cutCGapMyAmplitudeFT0AMin{"cutCGapMyAmplitudeFT0AMin", 0., {"My collision cut. A Gap"}}; - Configurable cutCGapMyEnergyZNCMax{"cutCGapMyEnergyZNCMax", 0., {"My collision cut. C Gap"}}; + Configurable cutGapCMyEnergyZNC{"cutGapCMyEnergyZNC", 0., {"My collision cut. C Gap"}}; // Configurable cutCGapMyAmplitudeFT0CMax{"cutCGapMyAmplitudeFT0CMax", 200., {"My collision cut. A Gap"}}; // Declare configurables on tracks - Configurable cutMyptMin{"cutMyptMin", 0.15, {"My Track cut"}}; - Configurable cutMyptMax{"cutMyptMax", 10., {"My Track cut"}}; - Configurable cutMyetaMin{"cutMyetaMin", -0.9, {"My Track cut"}}; - Configurable cutMyetaMax{"cutMyetaMax", 0.9, {"My Track cut"}}; + Configurable cutMyptMin{"cutMyptMin", 0.2, {"My Track cut"}}; + Configurable cutMyptMax{"cutMyptMax", 3., {"My Track cut"}}; + Configurable cutMyetaMin{"cutMyetaMin", -0.8, {"My Track cut"}}; + Configurable cutMyetaMax{"cutMyetaMax", 0.8, {"My Track cut"}}; Configurable cutMydcaZmax{"cutMydcaZmax", 2.f, {"My Track cut"}}; Configurable cutMydcaXYmax{"cutMydcaXYmax", 1e0f, {"My Track cut"}}; Configurable cutMydcaXYusePt{"cutMydcaXYusePt", false, {"My Track cut"}}; @@ -133,6 +137,10 @@ struct upcPhotonuclearAnalysisJMG { Configurable cutMyTPCNClsCrossedRowsOverNClsFindableMin{"cutMyTPCNClsCrossedRowsOverNClsFindableMin", 0.8f, {"My Track cut"}}; Configurable cutMyTPCNClsOverFindableNClsMin{"cutMyTPCNClsOverFindableNClsMin", 0.5f, {"My Track cut"}}; Configurable cutMyTPCChi2NclMax{"cutMyTPCChi2NclMax", 4.f, {"My Track cut"}}; + Configurable myWeightMin{"myWeightMin", 0.2f, {"My Track cut"}}; + Configurable myWeightMax{"myWeightMax", 5.f, {"My Track cut"}}; + Configurable myEpsilonToWeight{"myEpsilonToWeight", 1e-6f, {"My Track cut"}}; + Configurable useEpsilon{"useEpsilon", false, {"My Track cut"}}; Configurable> cfgPairCut{"cfgPairCut", {CFGPairCutDefaults[0], 5, @@ -144,22 +152,26 @@ struct upcPhotonuclearAnalysisJMG { ConfigurableAxis axisDeltaEta{"axisDeltaEta", {40, -2, 2}, "delta eta axis for histograms"}; ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"}; ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0}, "pt associated axis for histograms"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110.1}, "multiplicity / multiplicity axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110.1}, "multiplicity / multiplicity axis for histograms"}; ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; Filter collisionZVtxFilter = nabs(aod::collision::posZ) < myZVtxCut; Filter collisionZNTimeFilter = nabs(aod::udzdc::timeZNA) < myTimeZNACut && nabs(aod::udzdc::timeZNC) < myTimeZNCCut; + Filter collisionZNeEnergyFilter = (aod::udzdc::energyCommonZNA < cutGapAMyEnergyZNA && aod::udzdc::energyCommonZNC >= cutGapAMyEnergyZNC) || (aod::udzdc::energyCommonZNA >= cutGapCMyEnergyZNA && aod::udzdc::energyCommonZNC < cutGapCMyEnergyZNC); + Filter collisioSGFilter = aod::udcollision::gapSide == uint8_t(0) || aod::udcollision::gapSide == uint8_t(1); using FullSGUDCollision = soa::Filtered>; using FullUDTracks = soa::Join; // Output definitions - OutputObj sameGapSideA{"sameEventGapSideA"}; - OutputObj mixedGapSideA{"mixedEventGapSideA"}; - OutputObj sameGapSideC{"sameEventGapSideC"}; - OutputObj mixedGapSideC{"mixedEventGapSideC"}; + OutputObj same{"sameEvent"}; + OutputObj mixed{"mixedEvent"}; + // OutputObj sameGapSideA{"sameEventGapSideA"}; + // OutputObj mixedGapSideA{"mixedEventGapSideA"}; + // OutputObj sameGapSideC{"sameEventGapSideC"}; + // OutputObj mixedGapSideC{"mixedEventGapSideC"}; UPCPairCuts mPairCuts; bool doPairCuts = false; @@ -167,22 +179,25 @@ struct upcPhotonuclearAnalysisJMG { void init(InitContext const&) { const AxisSpec axisCollision{4, -0.5, 3.5}; - const AxisSpec axisZvtx{40, -20., 20.}; + const AxisSpec axisZvtx{20, -10., 10.}; const AxisSpec axisPt{402, -0.05, 20.05}; const AxisSpec axisP{402, -10.05, 10.05}; const AxisSpec axisTPCSignal{802, -0.05, 400.05}; - const AxisSpec axisPhi{64, -2 * PI, 2 * PI}; - const AxisSpec axisEta{50, -1.2, 1.2}; - const AxisSpec axisNch{201, -0.5, 200.5}; + const AxisSpec axisPhi{64, 0., TwoPI}; + const AxisSpec axisEta{32, -0.8, 0.8}; + const AxisSpec axisNch{601, -0.5, 600.5}; const AxisSpec axisZNEnergy{1002, -0.5, 500.5}; const AxisSpec axisZNTime{21, -10.5, 10.5}; const AxisSpec axisFT0Amplitud{201, -0.5, 200.5}; const AxisSpec axisNCls{201, -0.5, 200.5}; const AxisSpec axisChi2NCls{100, 0, 50}; const AxisSpec axisTPCNClsCrossedRowsMin{100, -0.05, 2.05}; + const AxisSpec axisCountTracks{17, -0.5, 16.5}; histos.add("yields", "multiplicity vs pT vs eta", {HistType::kTH3F, {{100, 0, 100, "multiplicity"}, {40, 0, 20, "p_{T}"}, {100, -2, 2, "#eta"}}}); - histos.add("etaphi", "multiplicity vs eta vs phi", {HistType::kTH3F, {{100, 0, 100, "multiplicity"}, {100, -2, 2, "#eta"}, {200, 0, 2 * PI, "#varphi"}}}); + histos.add("etaphi", "multiplicity vs eta vs phi", {HistType::kTH3F, {{100, 0, 100, "multiplicity"}, {100, -2, 2, "#eta"}, {64, 0., TwoPI, "#varphi"}}}); + histos.add("etaphiVtx", "vertex Z vs eta vs phi", {HistType::kTH3F, {{20, -10., 10., "vertex Z"}, {32, -0.8, 0.8, "#eta"}, {64, 0., TwoPI, "#varphi"}}}); + histos.add("weightNUA", "weight per bin", {HistType::kTH3F, {{20, -10., 10., "vertex Z"}, {32, -0.8, 0.8, "#eta"}, {64, 0., TwoPI, "#varphi"}}}); const int maxMixBin = axisMultiplicity->size() * axisVertex->size(); histos.add("eventcount", "bin", {HistType::kTH1F, {{maxMixBin + 2, -2.5, -0.5 + maxMixBin, "bin"}}}); @@ -197,6 +212,10 @@ struct upcPhotonuclearAnalysisJMG { doPairCuts = true; } histos.add("Events/hCountCollisions", "0 total - 1 side A - 2 side C - 3 both side; Number of analysed collision; counts", kTH1F, {axisCollision}); + histos.add("Events/hCountCollisionsMixed", "0 total - 1 side A - 2 side C - 3 both side; Number of analysed collision; counts", kTH1F, {axisCollision}); + histos.add("Tracks/hTracksAfterCuts", " ; ; counts", kTH1F, {axisCountTracks}); + histos.add("Tracks/hTrackPhiBeforeCorr", "#it{#phi} distribution before NUA correction; #it{#phi}; counts", kTH1F, {axisPhi}); + histos.add("Tracks/hTrackPhiAfterCorr", "#it{#phi} distribution after NUA correction; #it{#phi}; counts", kTH1F, {axisPhi}); // histos to selection gap in side A histos.add("Tracks/SGsideA/hTrackPt", "#it{p_{T}} distribution; #it{p_{T}}; counts", kTH1F, {axisPt}); @@ -228,6 +247,7 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Events/SGsideA/hTimeRelationSides", "Time in side A vs time in side C; Time in side A; Time in side C", kTH2F, {axisZNTime, axisZNTime}); histos.add("Events/SGsideA/hAmplitudFT0A", "Amplitud in side A distribution; Amplitud in side A; counts", kTH1F, {axisFT0Amplitud}); histos.add("Events/SGsideA/hAmplitudFT0C", "Amplitud in side C distribution; Amplitud in side C; counts", kTH1F, {axisFT0Amplitud}); + histos.add("Events/SGsideA/hTrackPV", "#it{Nch vs Nch(PV)}; #it{N_{ch}(PV)}; #it{N_{ch}}", kTH2F, {axisNch, axisNch}); // histos to selection gap in side C histos.add("Tracks/SGsideC/hTrackPt", "#it{p_{T}} distribution; #it{p_{T}}; counts", kTH1F, {axisPt}); @@ -259,6 +279,7 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Events/SGsideC/hTimeRelationSides", "Time in side A vs time in side C; Time in side A; Time in side C", kTH2F, {axisZNTime, axisZNTime}); histos.add("Events/SGsideC/hAmplitudFT0A", "Amplitud in side A distribution; Amplitud in side A; counts", kTH1F, {axisFT0Amplitud}); histos.add("Events/SGsideC/hAmplitudFT0C", "Amplitud in side C distribution; Amplitud in side C; counts", kTH1F, {axisFT0Amplitud}); + histos.add("Events/SGsideC/hTrackPV", "#it{Nch vs Nch(PV)}; #it{N_{ch}(PV)}; #it{N_{ch}}", kTH2F, {axisNch, axisNch}); std::vector corrAxis = {{axisDeltaEta, "#Delta#eta"}, {axisPtAssoc, "p_{T} (GeV/c)"}, @@ -270,52 +291,66 @@ struct upcPhotonuclearAnalysisJMG { {axisEtaEfficiency, "#eta"}, {axisPtEfficiency, "p_{T} (GeV/c)"}, {axisVertexEfficiency, "z-vtx (cm)"}}; - sameGapSideA.setObject(new CorrelationContainer("sameEventGapSideA", "sameEventGapSideA", corrAxis, effAxis, {})); - mixedGapSideA.setObject(new CorrelationContainer("mixedEventGapSideA", "mixedEventGapSideA", corrAxis, effAxis, {})); - sameGapSideC.setObject(new CorrelationContainer("sameEventGapSideC", "sameEventGapSideC", corrAxis, effAxis, {})); - mixedGapSideC.setObject(new CorrelationContainer("mixedEventGapSideC", "mixedEventGapSideC", corrAxis, effAxis, {})); + same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); + mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + // sameGapSideA.setObject(new CorrelationContainer("sameEventGapSideA", "sameEventGapSideA", corrAxis, effAxis, {})); + // mixedGapSideA.setObject(new CorrelationContainer("mixedEventGapSideA", "mixedEventGapSideA", corrAxis, effAxis, {})); + // sameGapSideC.setObject(new CorrelationContainer("sameEventGapSideC", "sameEventGapSideC", corrAxis, effAxis, {})); + // mixedGapSideC.setObject(new CorrelationContainer("mixedEventGapSideC", "mixedEventGapSideC", corrAxis, effAxis, {})); } std::vector vtxBinsEdges{VARIABLE_WIDTH, -10.0f, -7.0f, -5.0f, -2.5f, 0.0f, 2.5f, 5.0f, 7.0f, 10.0f}; std::vector gapSideBinsEdges{VARIABLE_WIDTH, -0.5, 0.5, 1.5}; SliceCache cache; - int countGapA = 0; - int countGapC = 0; + // int countEvents = 0; + // int countGapA = 0; + // int countGapC = 0; // Binning only on PosZ without multiplicity - // using BinningType = ColumnBinningPolicy; using BinningType = ColumnBinningPolicy; - BinningType bindingOnVtx{{vtxBinsEdges, gapSideBinsEdges}, true}; - SameKindPair pairs{bindingOnVtx, nEventsMixed, -1, &cache}; + // BinningType bindingOnVtx{{vtxBinsEdges, gapSideBinsEdges}, true}; + // using BinningType = ColumnBinningPolicy; + // BinningType bindingOnVtx{{vtxBinsEdges}, true}; + // SameKindPair pairs{bindingOnVtx, nEventsMixed, -1, &cache}; template bool isCollisionCutSG(CSG const& collision, int SideGap) { + bool gapSideA = (collision.energyCommonZNA() < cutGapAMyEnergyZNA) && (collision.energyCommonZNC() >= cutGapAMyEnergyZNC); + bool gapSideC = (collision.energyCommonZNA() >= cutGapCMyEnergyZNA) && (collision.energyCommonZNC() < cutGapCMyEnergyZNC); + switch (SideGap) { - case 0: // Gap in A side - if ((collision.energyCommonZNA() < cutAGapMyEnergyZNAMax && collision.energyCommonZNC() >= cutAGapMyEnergyZNCMin) == false) { // 0n - A side && Xn - C Side - return false; - } + case 0: // Gap in A side + return gapSideA; // 0n - A side && Xn - C Side // if ((collision.totalFT0AmplitudeA() < cutAGapMyAmplitudeFT0AMax && collision.totalFT0AmplitudeC() >= cutAGapMyAmplitudeFT0CMin) == false) { // return false; // } break; - case 1: // Gap in C side - if ((collision.energyCommonZNA() >= cutCGapMyEnergyZNAMin && collision.energyCommonZNC() < cutCGapMyEnergyZNCMax) == false) { // Xn - A side && 0n - C Side - return false; - } + case 1: // Gap in C side + return gapSideC; // Xn - A side && 0n - C Side // if ((collision.totalFT0AmplitudeA() >= cutCGapMyAmplitudeFT0AMin && collision.totalFT0AmplitudeC() < cutCGapMyAmplitudeFT0CMax) == false) { // return false; // } break; + default: + return false; + break; } - return true; + } + + template + bool isCollisionCutSG(CSG const& collision) + { + return isCollisionCutSG(collision, 0) || isCollisionCutSG(collision, 1); } template bool isTrackCut(T const& track) { + if (track.sign() != 1 && track.sign() != -1) { + return false; + } if (track.pt() < cutMyptMin || track.pt() > cutMyptMax) { return false; } @@ -335,6 +370,9 @@ struct upcPhotonuclearAnalysisJMG { return false; } } + if (track.isPVContributor() == false) { + return false; + } // Quality Track // ITS if (cutMyHasITS && !track.hasITS()) { @@ -372,11 +410,14 @@ struct upcPhotonuclearAnalysisJMG { } template - void fillQAUD(const TTracks tracks) + void fillQAUD(const TTracks tracks, float multiplicity) { for (const auto& track : tracks) { - histos.fill(HIST("yields"), tracks.size(), track.pt(), eta(track.px(), track.py(), track.pz())); - histos.fill(HIST("etaphi"), tracks.size(), eta(track.px(), track.py(), track.pz()), phi(track.px(), track.py())); + if (isTrackCut(track) == false) { + continue; + } + histos.fill(HIST("yields"), multiplicity, track.pt(), eta(track.px(), track.py(), track.pz())); + histos.fill(HIST("etaphi"), multiplicity, eta(track.px(), track.py(), track.pz()), phi(track.px(), track.py())); } } @@ -394,7 +435,7 @@ struct upcPhotonuclearAnalysisJMG { multiplicity = tracks1.size(); for (const auto& track1 : tracks1) { if (isTrackCut(track1) == false) { - continue; + return; } target->getTriggerHist()->Fill(CorrelationContainer::kCFStepReconstructed, track1.pt(), multiplicity, posZ, 1.0); for (const auto& track2 : tracks2) { @@ -402,35 +443,96 @@ struct upcPhotonuclearAnalysisJMG { continue; } if (isTrackCut(track2) == false) { - continue; + return; } - if (doPairCuts && mPairCuts.conversionCuts(track1, track2)) { + /*if (doPairCuts && mPairCuts.conversionCuts(track1, track2)) { continue; - } + }*/ float deltaPhi = phi(track1.px(), track1.py()) - phi(track2.px(), track2.py()); - if (deltaPhi > 1.5f * PI) { - deltaPhi -= TwoPI; + deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf, kThreeHalfPi); + target->getPairHist()->Fill(CorrelationContainer::kCFStepReconstructed, eta(track1.px(), track1.py(), track1.pz()) - eta(track2.px(), track2.py(), track2.pz()), track2.pt(), track1.pt(), multiplicity, deltaPhi, posZ, 1.0); + } + } + } + + void makeNUAWeights(std::shared_ptr histoRaw3D) + { + const int nPhi = histoRaw3D->GetZaxis()->GetNbins(); + const int nEta = histoRaw3D->GetYaxis()->GetNbins(); + const int nVz = histoRaw3D->GetXaxis()->GetNbins(); + + for (int jEtha = 1; jEtha <= nEta; ++jEtha) { + for (int iVtxZ = 1; iVtxZ <= nVz; ++iVtxZ) { + // average on phi to (eta_jEtha, vz_iVtxZ) + double sum = 0, count = 0; + for (int kPhi = 1; kPhi <= nPhi; ++kPhi) { + sum += histoRaw3D->GetBinContent(iVtxZ, jEtha, kPhi); + count += 1.0; } - if (deltaPhi < -PIHalf) { - deltaPhi += TwoPI; + const double nMean = (count > 0) ? sum / count : 0.0; + + for (int kPhi = 1; kPhi <= nPhi; ++kPhi) { + double nEntry = histoRaw3D->GetBinContent(iVtxZ, jEtha, kPhi); + double w; + if (useEpsilon) { + if (nMean > 0) { + w = nMean / std::max(nEntry, static_cast(myEpsilonToWeight)); + } else { + w = 1.0; + } + } else { + if (nMean > 0) { + w = nMean / nEntry; + } else { + w = 1.0; + } + } + if (w < myWeightMin) + w = myWeightMin; + if (w > myWeightMax) + w = myWeightMax; + if (auto histoWeightNUA = histos.get(HIST("weightNUA"))) { + histoWeightNUA->SetBinContent(iVtxZ, jEtha, kPhi, w); + } } - target->getPairHist()->Fill(CorrelationContainer::kCFStepReconstructed, eta(track1.px(), track1.py(), track1.pz()) - eta(track2.px(), track2.py(), track2.pz()), track2.pt(), track1.pt(), multiplicity, deltaPhi, posZ, 1.0); } } } + float getNUAWeight(float vz, float eta, float phi) + { + auto hWeight = histos.get(HIST("weightNUA")); + phi = RecoDecay::constrainAngle(phi, 0.f, TwoPI); + int iPhi = hWeight->GetZaxis()->FindBin(phi); + int iEta = hWeight->GetYaxis()->FindBin(eta); + int iVz = hWeight->GetXaxis()->FindBin(vz); + return hWeight->GetBinContent(iVz, iEta, iPhi); + } + void processSG(FullSGUDCollision::iterator const& reconstructedCollision, FullUDTracks const& reconstructedTracks) { histos.fill(HIST("Events/hCountCollisions"), 0); int sgSide = reconstructedCollision.gapSide(); int nTracksCharged = 0; float sumPt = 0; + int nchPVGapSideA = 0; + int nchPVGapSideC = 0; + int nchGapSideA = 0; + int nchGapSideC = 0; std::vector vTrackPtSideA, vTrackEtaSideA, vTrackPhiSideA, vTrackTPCSignalSideA, vTrackTOFSignalSideA, vTrackTPCNSigmaPiSideA, vTrackTOFNSigmaPiSideA, vTrackTPCNSigmaKaSideA, vTrackTOFNSigmaKaSideA; std::vector vTrackPtSideC, vTrackEtaSideC, vTrackPhiSideC, vTrackTPCSignalSideC, vTrackTOFSignalSideC, vTrackTPCNSigmaPiSideC, vTrackTOFNSigmaPiSideC, vTrackTPCNSigmaKaSideC, vTrackTOFNSigmaKaSideC; int nTracksChargedSideA(-222), nTracksChargedSideC(-222); int multiplicitySideA(-222), multiplicitySideC(-222); + for (const auto& track : reconstructedTracks) { + if (isTrackCut(track) == false) { + continue; + } + histos.fill(HIST("etaphiVtx"), reconstructedCollision.posZ(), eta(track.px(), track.py(), track.pz()), phi(track.px(), track.py())); + histos.fill(HIST("Tracks/hTrackPhiBeforeCorr"), phi(track.px(), track.py())); + } + switch (sgSide) { case 0: // gap for side A if (isCollisionCutSG(reconstructedCollision, 0) == false) { @@ -447,43 +549,47 @@ struct upcPhotonuclearAnalysisJMG { histos.fill(HIST("Events/SGsideA/hAmplitudFT0A"), reconstructedCollision.totalFT0AmplitudeA()); histos.fill(HIST("Events/SGsideA/hAmplitudFT0C"), reconstructedCollision.totalFT0AmplitudeC()); for (const auto& track : reconstructedTracks) { - if (track.sign() == 1 || track.sign() == -1) { - if (isTrackCut(track) == false) { - continue; - } - nTracksCharged++; - sumPt += track.pt(); - histos.fill(HIST("Tracks/SGsideA/hTrackPt"), track.pt()); - histos.fill(HIST("Tracks/SGsideA/hTrackPhi"), phi(track.px(), track.py())); - histos.fill(HIST("Tracks/SGsideA/hTrackEta"), eta(track.px(), track.py(), track.pz())); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); - histos.fill(HIST("Tracks/SGsideA/hTrackTOFSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tofSignal()); - vTrackPtSideA.push_back(track.pt()); - vTrackEtaSideA.push_back(eta(track.px(), track.py(), track.pz())); - vTrackPhiSideA.push_back(phi(track.px(), track.py())); - vTrackTPCSignalSideA.push_back(track.tpcSignal()); - vTrackTOFSignalSideA.push_back(track.tofSignal()); - vTrackTPCNSigmaPiSideA.push_back(track.tpcNSigmaPi()); - vTrackTOFNSigmaPiSideA.push_back(track.tofNSigmaPi()); - vTrackTPCNSigmaKaSideA.push_back(track.tpcNSigmaKa()); - vTrackTOFNSigmaKaSideA.push_back(track.tofNSigmaKa()); - - histos.fill(HIST("Tracks/SGsideA/hTrackITSNCls"), track.itsNCls()); - histos.fill(HIST("Tracks/SGsideA/hTrackITSChi2NCls"), track.itsChi2NCl()); - histos.fill(HIST("Tracks/SGsideA/hTrackNClsCrossedRowsOverNClsFindable"), (static_cast(track.tpcNClsCrossedRows()) / static_cast(track.tpcNClsFindable()))); - histos.fill(HIST("Tracks/SGsideA/hTrackNClsCrossedRowsOverNCls"), (static_cast(track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()) / static_cast(track.tpcNClsFindable()))); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFindable"), track.tpcNClsFindable()); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFound"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFindableMinusFound"), track.tpcNClsFindableMinusFound()); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFindableMinusCrossedRows"), track.tpcNClsFindableMinusCrossedRows()); - histos.fill(HIST("Tracks/SGsideA/hTrackTPCChi2NCls"), track.tpcChi2NCl()); - histos.fill(HIST("Tracks/SGsideA/hTrackITSNClsTPCCls"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound(), track.itsNCls()); + // LOGF(debug, "Filling tracks. Gap Side A"); + ++nchGapSideA; + if (track.isPVContributor() == true) { + ++nchPVGapSideA; + } + if (isTrackCut(track) == false) { + continue; } + nTracksCharged++; + sumPt += track.pt(); + histos.fill(HIST("Tracks/SGsideA/hTrackPt"), track.pt()); + histos.fill(HIST("Tracks/SGsideA/hTrackPhi"), phi(track.px(), track.py())); + histos.fill(HIST("Tracks/SGsideA/hTrackEta"), eta(track.px(), track.py(), track.pz())); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); + histos.fill(HIST("Tracks/SGsideA/hTrackTOFSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tofSignal()); + vTrackPtSideA.push_back(track.pt()); + vTrackEtaSideA.push_back(eta(track.px(), track.py(), track.pz())); + vTrackPhiSideA.push_back(phi(track.px(), track.py())); + vTrackTPCSignalSideA.push_back(track.tpcSignal()); + vTrackTOFSignalSideA.push_back(track.tofSignal()); + vTrackTPCNSigmaPiSideA.push_back(track.tpcNSigmaPi()); + vTrackTOFNSigmaPiSideA.push_back(track.tofNSigmaPi()); + vTrackTPCNSigmaKaSideA.push_back(track.tpcNSigmaKa()); + vTrackTOFNSigmaKaSideA.push_back(track.tofNSigmaKa()); + + histos.fill(HIST("Tracks/SGsideA/hTrackITSNCls"), track.itsNCls()); + histos.fill(HIST("Tracks/SGsideA/hTrackITSChi2NCls"), track.itsChi2NCl()); + histos.fill(HIST("Tracks/SGsideA/hTrackNClsCrossedRowsOverNClsFindable"), (static_cast(track.tpcNClsCrossedRows()) / static_cast(track.tpcNClsFindable()))); + histos.fill(HIST("Tracks/SGsideA/hTrackNClsCrossedRowsOverNCls"), (static_cast(track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()) / static_cast(track.tpcNClsFindable()))); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFindable"), track.tpcNClsFindable()); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFound"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFindableMinusFound"), track.tpcNClsFindableMinusFound()); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCNClsFindableMinusCrossedRows"), track.tpcNClsFindableMinusCrossedRows()); + histos.fill(HIST("Tracks/SGsideA/hTrackTPCChi2NCls"), track.tpcChi2NCl()); + histos.fill(HIST("Tracks/SGsideA/hTrackITSNClsTPCCls"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound(), track.itsNCls()); } histos.fill(HIST("Events/SGsideA/hNch"), nTracksCharged); histos.fill(HIST("Events/SGsideA/hMultiplicity"), reconstructedTracks.size()); histos.fill(HIST("Events/SGsideA/hPtVSNch"), nTracksCharged, (sumPt / nTracksCharged)); + histos.fill(HIST("Events/SGsideA/hTrackPV"), nchPVGapSideA, nchGapSideA); nTracksChargedSideA = nTracksCharged; multiplicitySideA = reconstructedTracks.size(); nTracksCharged = sumPt = 0; @@ -503,43 +609,46 @@ struct upcPhotonuclearAnalysisJMG { histos.fill(HIST("Events/SGsideC/hAmplitudFT0A"), reconstructedCollision.totalFT0AmplitudeA()); histos.fill(HIST("Events/SGsideC/hAmplitudFT0C"), reconstructedCollision.totalFT0AmplitudeC()); for (const auto& track : reconstructedTracks) { - if (track.sign() == 1 || track.sign() == -1) { - if (isTrackCut(track) == false) { - continue; - } - nTracksCharged++; - sumPt += track.pt(); - histos.fill(HIST("Tracks/SGsideC/hTrackPt"), track.pt()); - histos.fill(HIST("Tracks/SGsideC/hTrackPhi"), phi(track.px(), track.py())); - histos.fill(HIST("Tracks/SGsideC/hTrackEta"), eta(track.px(), track.py(), track.pz())); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); - histos.fill(HIST("Tracks/SGsideC/hTrackTOFSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tofSignal()); - vTrackPtSideC.push_back(track.pt()); - vTrackEtaSideC.push_back(eta(track.px(), track.py(), track.pz())); - vTrackPhiSideC.push_back(phi(track.px(), track.py())); - vTrackTPCSignalSideC.push_back(track.tpcSignal()); - vTrackTOFSignalSideC.push_back(track.tofSignal()); - vTrackTPCNSigmaPiSideC.push_back(track.tpcNSigmaPi()); - vTrackTOFNSigmaPiSideC.push_back(track.tofNSigmaPi()); - vTrackTPCNSigmaKaSideC.push_back(track.tpcNSigmaKa()); - vTrackTOFNSigmaKaSideC.push_back(track.tofNSigmaKa()); - - histos.fill(HIST("Tracks/SGsideC/hTrackITSNCls"), track.itsNCls()); - histos.fill(HIST("Tracks/SGsideC/hTrackITSChi2NCls"), track.itsChi2NCl()); - histos.fill(HIST("Tracks/SGsideC/hTrackNClsCrossedRowsOverNClsFindable"), (static_cast(track.tpcNClsCrossedRows()) / static_cast(track.tpcNClsFindable()))); - histos.fill(HIST("Tracks/SGsideC/hTrackNClsCrossedRowsOverNCls"), (static_cast(track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()) / static_cast(track.tpcNClsFindable()))); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFindable"), track.tpcNClsFindable()); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFound"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFindableMinusFound"), track.tpcNClsFindableMinusFound()); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFindableMinusCrossedRows"), track.tpcNClsFindableMinusCrossedRows()); - histos.fill(HIST("Tracks/SGsideC/hTrackTPCChi2NCls"), track.tpcChi2NCl()); - histos.fill(HIST("Tracks/SGsideC/hTrackITSNClsTPCCls"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound(), track.itsNCls()); + ++nchGapSideC; + if (track.isPVContributor() == true) { + ++nchPVGapSideC; + } + if (isTrackCut(track) == false) { + continue; } + nTracksCharged++; + sumPt += track.pt(); + histos.fill(HIST("Tracks/SGsideC/hTrackPt"), track.pt()); + histos.fill(HIST("Tracks/SGsideC/hTrackPhi"), phi(track.px(), track.py())); + histos.fill(HIST("Tracks/SGsideC/hTrackEta"), eta(track.px(), track.py(), track.pz())); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); + histos.fill(HIST("Tracks/SGsideC/hTrackTOFSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tofSignal()); + vTrackPtSideC.push_back(track.pt()); + vTrackEtaSideC.push_back(eta(track.px(), track.py(), track.pz())); + vTrackPhiSideC.push_back(phi(track.px(), track.py())); + vTrackTPCSignalSideC.push_back(track.tpcSignal()); + vTrackTOFSignalSideC.push_back(track.tofSignal()); + vTrackTPCNSigmaPiSideC.push_back(track.tpcNSigmaPi()); + vTrackTOFNSigmaPiSideC.push_back(track.tofNSigmaPi()); + vTrackTPCNSigmaKaSideC.push_back(track.tpcNSigmaKa()); + vTrackTOFNSigmaKaSideC.push_back(track.tofNSigmaKa()); + + histos.fill(HIST("Tracks/SGsideC/hTrackITSNCls"), track.itsNCls()); + histos.fill(HIST("Tracks/SGsideC/hTrackITSChi2NCls"), track.itsChi2NCl()); + histos.fill(HIST("Tracks/SGsideC/hTrackNClsCrossedRowsOverNClsFindable"), (static_cast(track.tpcNClsCrossedRows()) / static_cast(track.tpcNClsFindable()))); + histos.fill(HIST("Tracks/SGsideC/hTrackNClsCrossedRowsOverNCls"), (static_cast(track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()) / static_cast(track.tpcNClsFindable()))); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFindable"), track.tpcNClsFindable()); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFound"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFindableMinusFound"), track.tpcNClsFindableMinusFound()); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCNClsFindableMinusCrossedRows"), track.tpcNClsFindableMinusCrossedRows()); + histos.fill(HIST("Tracks/SGsideC/hTrackTPCChi2NCls"), track.tpcChi2NCl()); + histos.fill(HIST("Tracks/SGsideC/hTrackITSNClsTPCCls"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound(), track.itsNCls()); } histos.fill(HIST("Events/SGsideC/hNch"), nTracksCharged); histos.fill(HIST("Events/SGsideC/hMultiplicity"), reconstructedTracks.size()); histos.fill(HIST("Events/SGsideC/hPtVSNch"), nTracksCharged, (sumPt / nTracksCharged)); + histos.fill(HIST("Events/SGsideC/hTrackPV"), nchPVGapSideC, nchGapSideC); nTracksChargedSideC = nTracksCharged; multiplicitySideC = reconstructedTracks.size(); nTracksCharged = sumPt = 0; @@ -551,14 +660,214 @@ struct upcPhotonuclearAnalysisJMG { tree(vTrackPtSideA, vTrackEtaSideA, vTrackPhiSideA, vTrackTPCSignalSideA, vTrackTOFSignalSideA, vTrackTPCNSigmaPiSideA, vTrackTOFNSigmaPiSideA, vTrackTPCNSigmaKaSideA, vTrackTOFNSigmaKaSideA, vTrackPtSideC, vTrackEtaSideC, vTrackPhiSideC, vTrackTPCSignalSideA, vTrackTOFSignalSideA, vTrackTPCNSigmaPiSideA, vTrackTOFNSigmaPiSideA, vTrackTPCNSigmaKaSideA, vTrackTOFNSigmaKaSideA, nTracksChargedSideA, multiplicitySideA, nTracksChargedSideC, multiplicitySideC); // nTracksChargedSideA = nTracksChargedSideC = multiplicitySideA = multiplicitySideC = 0; } - PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processSG, "Process in UD tables", true); + + PROCESS_SWITCH(UpcPhotonuclearAnalysisJMG, processSG, "Process in UD tables", true); + + void processMixed(FullSGUDCollision const& reconstructedCollision, FullUDTracks const& reconstructedTracks) + { + // (void)reconstructedCollision; + // int sgSide = reconstructedCollision.gapSide(); + // int sgSide = 0; + + // int maxCount = 0; + // int maxCountGapA = 0; + // int maxCountGapC = 0; + + // if (auto histEventCount = histos.get(HIST("eventcount"))) { + // int binA = histEventCount->GetXaxis()->FindBin(-2); Gap A + // int binC = histEventCount->GetXaxis()->FindBin(-1); Gap C + + // maxCount = histEventCount->GetBinContent(binA) * factorEventsMixed; + // maxCountGapA = histEventCount->GetBinContent(binA) * factorEventsMixed; + // maxCountGapC = histEventCount->GetBinContent(binC) * factorEventsMixed; + // } + + auto histoEthaPhiVtxZ = histos.get(HIST("etaphiVtx")); + makeNUAWeights(histoEthaPhiVtxZ); + + BinningType bindingOnVtx{{vtxBinsEdges, gapSideBinsEdges}, true}; + // BinningType bindingOnVtx{{vtxBinsEdges}, true}; + auto tracksTuple = std::make_tuple(reconstructedTracks); + SameKindPair pairs{bindingOnVtx, nEventsMixed, -1, reconstructedCollision, tracksTuple, &cache}; + + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + if (collision1.size() == 0 || collision2.size() == 0) { + // LOGF(info, "One or both collisions are empty."); + continue; + } + + // if (countGapA >= maxCountGapA && countGapC >= maxCountGapC) { + // break; + // } + + float multiplicity = 0; + + histos.fill(HIST("Events/hCountCollisionsMixed"), 0); + + if (isCollisionCutSG(collision1) == false || isCollisionCutSG(collision2) == false) { + continue; + } + histos.fill(HIST("Events/hCountCollisionsMixed"), 1); + // ++countEvents; + // LOGF(info, "In the pairs loop"); + for (const auto& track : tracks1) { + if (isTrackCut(track) == false) { + continue; + } + ++multiplicity; + } + // multiplicity = tracks1.size(); + if (fillCollisionUD(mixed, multiplicity) == false) { + return; + } + histos.fill(HIST("Events/hCountCollisionsMixed"), 2); + // histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ()})); + histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ(), collision1.gapSide()})); + fillCorrelationsUD(mixed, tracks1, tracks2, multiplicity, collision1.posZ()); + // LOGF(info, "Filling mixed events"); + + // if (collision1.gapSide() == 0 && collision2.gapSide() == 0) { gap on side A + // if (isCollisionCutSG(collision1, 0) == false && isCollisionCutSG(collision2, 0) == false) { + // continue; + // } + // std::cout << "Counts for Gap A: " << countGapA << " Maximum Count for Gap A " << maxCountGapA << std::endl; + // ++countGapA; + // LOGF(info, "In the pairs loop, gap side A"); + // multiplicity = tracks1.size(); + // if (fillCollisionUD(mixedGapSideA, multiplicity) == false) { + // return; + // } + // histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ()})); + // histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ(), collision1.gapSide()})); + // fillCorrelationsUD(mixedGapSideA, tracks1, tracks2, multiplicity, collision1.posZ()); + // LOGF(info, "Filling mixedGapSideA events, Gap for side A"); + // } + + // if (collision1.gapSide() == 1 && collision2.gapSide() == 1) { gap on side C + // if (isCollisionCutSG(collision1, 1) == false && isCollisionCutSG(collision2, 1) == false) { + // continue; + // } + // std::cout << "Counts for Gap C: " << countGapC << " Maximum Count for Gap C" << maxCountGapC << std::endl; + // ++countGapC; + // LOGF(info, "In the pairs loop, gap side C"); + // multiplicity = tracks1.size(); + // if (fillCollisionUD(mixedGapSideC, multiplicity) == false) { + // return; + // } + // fillCorrelationsUD(mixedGapSideC, tracks1, tracks2, multiplicity, collision1.posZ()); + // LOGF(info, "Filling mixedGapSideC events, Gap for side C"); + // } else { + // continue; + // } + } + } + + PROCESS_SWITCH(UpcPhotonuclearAnalysisJMG, processMixed, "Process mixed events", true); void processSame(FullSGUDCollision::iterator const& reconstructedCollision, FullUDTracks const& reconstructedTracks) { - int sgSide = reconstructedCollision.gapSide(); + // int sgSide = reconstructedCollision.gapSide(); float multiplicity = 0; - switch (sgSide) { + if (isCollisionCutSG(reconstructedCollision) == false) { + return; + } + for (const auto& track : reconstructedTracks) { + histos.fill(HIST("Tracks/hTracksAfterCuts"), 0); + if (track.sign() != 1 && track.sign() != -1) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 1); + if (track.pt() < cutMyptMin || track.pt() > cutMyptMax) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 2); + if (eta(track.px(), track.py(), track.pz()) < cutMyetaMin || eta(track.px(), track.py(), track.pz()) > cutMyetaMax) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 3); + if (std::abs(track.dcaZ()) > cutMydcaZmax) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 4); + if (cutMydcaXYusePt) { + float maxDCA = 0.0105f + 0.0350f / std::pow(track.pt(), 1.1f); + if (std::abs(track.dcaXY()) > maxDCA) { + continue; + } + } else { + if (std::abs(track.dcaXY()) > cutMydcaXYmax) { + continue; + } + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 5); + if (track.isPVContributor() == false) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 6); + // Quality Track + // ITS + if (cutMyHasITS && !track.hasITS()) { + continue; // ITS refit + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 7); + if (track.itsNCls() < cutMyITSNClsMin) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 8); + if (track.itsChi2NCl() > cutMyITSChi2NClMax) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 9); + // TPC + if (cutMyHasTPC && !track.hasTPC()) { + continue; // TPC refit + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 10); + if (track.tpcNClsCrossedRows() < cutMyTPCNClsCrossedRowsMin) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 11); + if ((track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()) < cutMyTPCNClsMin) { + continue; // tpcNClsFound() + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 12); + if (track.tpcNClsFindable() < cutMyTPCNClsFindableMin) { + continue; + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 13); + if ((static_cast(track.tpcNClsCrossedRows()) / static_cast(track.tpcNClsFindable())) < cutMyTPCNClsCrossedRowsOverNClsFindableMin) { + continue; // + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 14); + if ((static_cast(track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()) / static_cast(track.tpcNClsFindable())) < cutMyTPCNClsCrossedRowsOverNClsFindableMin) { + continue; // + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 15); + if (track.tpcChi2NCl() > cutMyTPCChi2NclMax) { + continue; // TPC chi2 + } + histos.fill(HIST("Tracks/hTracksAfterCuts"), 16); + + if (isTrackCut(track) == false) { + continue; + } + ++multiplicity; + + float weightNUA = getNUAWeight(reconstructedCollision.posZ(), eta(track.px(), track.py(), track.pz()), phi(track.px(), track.py())); + + histos.fill(HIST("Tracks/hTrackPhiAfterCorr"), phi(track.px(), track.py()), weightNUA); + } + // multiplicity = reconstructedTracks.size(); + if (fillCollisionUD(same, multiplicity) == false) { + return; + } + // LOGF(debug, "Filling same events"); + histos.fill(HIST("eventcount"), -2); + fillQAUD(reconstructedTracks, multiplicity); + fillCorrelationsUD(same, reconstructedTracks, reconstructedTracks, multiplicity, reconstructedCollision.posZ()); + + /*switch (sgSide) { case 0: // gap for side A if (isCollisionCutSG(reconstructedCollision, 0) == false) { return; @@ -587,78 +896,13 @@ struct upcPhotonuclearAnalysisJMG { default: return; break; - } - } - - PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processSame, "Process same event", true); - - void processMixed(FullSGUDCollision::iterator const& reconstructedCollision) - { - (void)reconstructedCollision; - // int sgSide = reconstructedCollision.gapSide(); - // int sgSide = 0; - - int maxCountGapA = 0; - int maxCountGapC = 0; - - if (auto histEventCount = histos.get(HIST("eventcount"))) { - int binA = histEventCount->GetXaxis()->FindBin(-2); // Gap A - int binC = histEventCount->GetXaxis()->FindBin(-1); // Gap C - - maxCountGapA = histEventCount->GetBinContent(binA) * factorEventsMixed; - maxCountGapC = histEventCount->GetBinContent(binC) * factorEventsMixed; - } - - for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { - if (collision1.size() == 0 || collision2.size() == 0) { - // LOGF(info, "One or both collisions are empty."); - continue; - } - - if (countGapA >= maxCountGapA && countGapC >= maxCountGapC) { - break; - } - float multiplicity = 0; - if (collision1.gapSide() == 0 && collision2.gapSide() == 0) { // gap on side A - if (isCollisionCutSG(collision1, 0) == false && isCollisionCutSG(collision2, 0) == false) { - continue; - } - // std::cout << "Counts for Gap A: " << countGapA << " Maximum Count for Gap A " << maxCountGapA << std::endl; - ++countGapA; - // LOGF(info, "In the pairs loop, gap side A"); - multiplicity = tracks1.size(); - if (fillCollisionUD(mixedGapSideA, multiplicity) == false) { - return; - } - // histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ()})); - histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ(), collision1.gapSide()})); - fillCorrelationsUD(mixedGapSideA, tracks1, tracks2, multiplicity, collision1.posZ()); - // LOGF(info, "Filling mixedGapSideA events, Gap for side A"); - } - - if (collision1.gapSide() == 1 && collision2.gapSide() == 1) { // gap on side C - if (isCollisionCutSG(collision1, 1) == false && isCollisionCutSG(collision2, 1) == false) { - continue; - } - // std::cout << "Counts for Gap C: " << countGapC << " Maximum Count for Gap C" << maxCountGapC << std::endl; - ++countGapC; - // LOGF(info, "In the pairs loop, gap side C"); - multiplicity = tracks1.size(); - if (fillCollisionUD(mixedGapSideC, multiplicity) == false) { - return; - } - fillCorrelationsUD(mixedGapSideC, tracks1, tracks2, multiplicity, collision1.posZ()); - // LOGF(info, "Filling mixedGapSideC events, Gap for side C"); - } else { - continue; - } - } + }*/ } - PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processMixed, "Process mixed events", true); + PROCESS_SWITCH(UpcPhotonuclearAnalysisJMG, processSame, "Process same event", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"upcphotonuclear"})}; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/Tools/ML/model.cxx b/Tools/ML/model.cxx index 62ccd9f9839..a60abc65af5 100644 --- a/Tools/ML/model.cxx +++ b/Tools/ML/model.cxx @@ -42,17 +42,17 @@ namespace ml std::string OnnxModel::printShape(const std::vector& v) { std::stringstream ss(""); - for (size_t i = 0; i < v.size() - 1; i++) + for (std::size_t i = 0; i < v.size() - 1; i++) ss << v[i] << "x"; ss << v[v.size() - 1]; return ss.str(); } -bool OnnxModel::checkHyperloop(bool verbose) +bool OnnxModel::checkHyperloop(const bool verbose) { /// Testing hyperloop core settings const char* alienCores = gSystem->Getenv("ALIEN_JDL_CPUCORES"); - bool alienCoresFound = (alienCores != NULL); + const bool alienCoresFound = (alienCores != NULL); if (alienCoresFound) { if (verbose) { LOGP(info, "Hyperloop test/Grid job detected! Number of cores = {}. Setting threads anyway to 1.", alienCores); @@ -68,7 +68,7 @@ bool OnnxModel::checkHyperloop(bool verbose) return alienCoresFound; } -void OnnxModel::initModel(std::string localPath, bool enableOptimizations, int threads, uint64_t from, uint64_t until) +void OnnxModel::initModel(const std::string& localPath, const bool enableOptimizations, const int threads, const uint64_t from, const uint64_t until) { assert(from <= until); @@ -90,26 +90,26 @@ void OnnxModel::initModel(std::string localPath, bool enableOptimizations, int t mEnv = std::make_shared(ORT_LOGGING_LEVEL_WARNING, "onnx-model"); mSession = std::make_shared(*mEnv, modelPath.c_str(), sessionOptions); - Ort::AllocatorWithDefaultOptions tmpAllocator; - for (size_t i = 0; i < mSession->GetInputCount(); ++i) { + Ort::AllocatorWithDefaultOptions const tmpAllocator; + for (std::size_t i = 0; i < mSession->GetInputCount(); ++i) { mInputNames.push_back(mSession->GetInputNameAllocated(i, tmpAllocator).get()); } - for (size_t i = 0; i < mSession->GetInputCount(); ++i) { + for (std::size_t i = 0; i < mSession->GetInputCount(); ++i) { mInputShapes.emplace_back(mSession->GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); } - for (size_t i = 0; i < mSession->GetOutputCount(); ++i) { + for (std::size_t i = 0; i < mSession->GetOutputCount(); ++i) { mOutputNames.push_back(mSession->GetOutputNameAllocated(i, tmpAllocator).get()); } - for (size_t i = 0; i < mSession->GetOutputCount(); ++i) { + for (std::size_t i = 0; i < mSession->GetOutputCount(); ++i) { mOutputShapes.emplace_back(mSession->GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); } LOG(info) << "Input Nodes:"; - for (size_t i = 0; i < mInputNames.size(); i++) { + for (std::size_t i = 0; i < mInputNames.size(); i++) { LOG(info) << "\t" << mInputNames[i] << " : " << printShape(mInputShapes[i]); } LOG(info) << "Output Nodes:"; - for (size_t i = 0; i < mOutputNames.size(); i++) { + for (std::size_t i = 0; i < mOutputNames.size(); i++) { LOG(info) << "\t" << mOutputNames[i] << " : " << printShape(mOutputShapes[i]); } @@ -121,7 +121,7 @@ void OnnxModel::initModel(std::string localPath, bool enableOptimizations, int t LOG(info) << "--- Model initialized! ---"; } -void OnnxModel::setActiveThreads(int threads) +void OnnxModel::setActiveThreads(const int threads) { activeThreads = threads; if (!checkHyperloop(false)) { diff --git a/Tools/ML/model.h b/Tools/ML/model.h index e08b84f129f..468c3dfd733 100644 --- a/Tools/ML/model.h +++ b/Tools/ML/model.h @@ -47,7 +47,7 @@ class OnnxModel ~OnnxModel() = default; // Inferencing - void initModel(std::string, bool = false, int = 0, uint64_t = 0, uint64_t = 0); + void initModel(const std::string&, const bool = false, const int = 0, const uint64_t = 0, const uint64_t = 0); // template methods -- best to define them in header template @@ -57,7 +57,7 @@ class OnnxModel // assert(input[0].GetTensorTypeAndShapeInfo().GetShape() == getNumInputNodes()); --> Fails build in debug mode, TODO: assertion should be checked somehow try { - Ort::RunOptions runOptions; + const Ort::RunOptions runOptions; std::vector inputNamesChar(mInputNames.size(), nullptr); std::transform(std::begin(mInputNames), std::end(mInputNames), std::begin(inputNamesChar), [&](const std::string& str) { return str.c_str(); }); @@ -87,7 +87,7 @@ class OnnxModel template T* evalModel(std::vector& input) { - int64_t size = input.size(); + const int64_t size = input.size(); assert(size % mInputShapes[0][1] == 0); std::vector inputShape{size / mInputShapes[0][1], mInputShapes[0][1]}; std::vector inputTensors; @@ -106,16 +106,16 @@ class OnnxModel Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); - for (size_t iinput = 0; iinput < input.size(); iinput++) { + for (std::size_t iinput = 0; iinput < input.size(); iinput++) { [[maybe_unused]] int totalSize = 1; int64_t size = input[iinput].size(); - for (size_t idim = 1; idim < mInputShapes[iinput].size(); idim++) { + for (std::size_t idim = 1; idim < mInputShapes[iinput].size(); idim++) { totalSize *= mInputShapes[iinput][idim]; } assert(size % totalSize == 0); std::vector inputShape{static_cast(size / totalSize)}; - for (size_t idim = 1; idim < mInputShapes[iinput].size(); idim++) { + for (std::size_t idim = 1; idim < mInputShapes[iinput].size(); idim++) { inputShape.push_back(mInputShapes[iinput][idim]); } @@ -142,7 +142,7 @@ class OnnxModel int getNumOutputNodes() const { return mOutputShapes[0][1]; } uint64_t getValidityFrom() const { return validFrom; } uint64_t getValidityUntil() const { return validUntil; } - void setActiveThreads(int); + void setActiveThreads(const int); private: // Environment variables for the ONNX runtime @@ -164,7 +164,7 @@ class OnnxModel // Internal function for printing the shape of tensors std::string printShape(const std::vector&); - bool checkHyperloop(bool = true); + bool checkHyperloop(const bool = true); }; } // namespace ml diff --git a/Tutorials/src/filters.cxx b/Tutorials/src/filters.cxx index a3c590b8bfd..7411db8b7ab 100644 --- a/Tutorials/src/filters.cxx +++ b/Tutorials/src/filters.cxx @@ -10,110 +10,65 @@ // or submit itself to any jurisdiction. /// /// \brief Filters are used to select specific rows of a table. -/// \author -/// \since +/// \author Anton Alkin (anton.alkin@cern.ch) +/// \file filters.cxx -#include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" -namespace o2::aod -{ -namespace etaphi -{ -DECLARE_SOA_COLUMN(NPhi, nphi, float); -DECLARE_SOA_EXPRESSION_COLUMN(CosPhi, cosphi, float, - ncos(aod::etaphi::nphi)); -} // namespace etaphi -namespace track -{ -DECLARE_SOA_EXPRESSION_COLUMN(SPt, spt, float, - nabs(aod::track::sigma1Pt / aod::track::signed1Pt)); -} -DECLARE_SOA_TABLE(TPhi, "AOD", "TPHI", - etaphi::NPhi); -DECLARE_SOA_EXTENDED_TABLE_USER(EPhi, TPhi, "EPHI", - aod::etaphi::CosPhi); -using etracks = soa::Join; -DECLARE_SOA_EXTENDED_TABLE_USER(MTracks, etracks, "MTRACK", - aod::track::SPt); -} // namespace o2::aod +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -// production of table o2::aod::TPhi -struct ProduceTPhi { - Produces tphi; - void process(aod::Tracks const& tracks) - { - for (auto& track : tracks) { - tphi(track.phi()); - } - } -}; - // Apply filters on Collisions, Tracks, and TPhi -struct SpawnExtendedTables { - // spawn the extended tables - Spawns ephi; - Spawns mtrk; - - Configurable ptlow{"ptlow", 0.5f, ""}; - Configurable ptup{"ptup", 2.0f, ""}; - Filter ptFilter_a = aod::track::pt > ptlow; - Filter ptFilter_b = aod::track::pt < ptup; +struct Filters { + Configurable ptLow{"ptLow", 0.5f, ""}; + Configurable ptUp{"ptUp", 2.0f, ""}; + Filter ptFilterA = aod::track::pt > ptLow; + Filter ptFilterB = aod::track::pt < ptUp; - Configurable etalow{"etalow", -1.0f, ""}; - Configurable etaup{"etaup", 1.0f, ""}; - Filter etafilter = (aod::track::eta < etaup) && (aod::track::eta > etalow); + Configurable etaLow{"etaLow", -1.0f, ""}; + Configurable etaUp{"etaUp", 1.0f, ""}; + Filter etafilter = (aod::track::eta < etaUp) && (aod::track::eta > etaLow); - float philow = 1.0f; - float phiup = 2.0f; - Filter phifilter = (aod::etaphi::nphi < phiup) && (aod::etaphi::nphi > philow); + Configurable phiLow{"phiLow", 1.0f, "Phi lower limit"}; + Configurable phiUp{"phiUp", 2.0f, "Phi upper limit"}; Configurable vtxZ{"vtxZ", 10.f, ""}; Filter posZfilter = nabs(aod::collision::posZ) < vtxZ; - Filter bitwiseFilter = (o2::aod::track::flags & static_cast(o2::aod::track::TPCrefit)) != 0u; + Filter bitwiseFilter = (aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor); - // process only collisions and tracks which pass all defined filter criteria - void process(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks) - { - LOGF(info, "Collision: %d [N = %d out of %d], -%.1f < %.3f < %.1f", - collision.globalIndex(), tracks.size(), tracks.tableSize(), (float)vtxZ, collision.posZ(), (float)vtxZ); - for (auto& track : tracks) { - LOGF(info, "id = %d; eta: %.3f < %.3f < %.3f; phi: %.3f < %.3f < %.3f; pt: %.3f < %.3f < %.3f", - track.collisionId(), (float)etalow, track.eta(), (float)etaup, philow, track.nphi(), phiup, (float)ptlow, track.pt(), (float)ptup); - } - } -}; + // it is now possible to set filters as strings + // note that column designators need the full prefix, i.e. o2::aod:: + // configurables can be used with ncfg(type, value, name) + // where value is the default value + // name is the full name in JSON, with prefix if there is any + Configurable extraFilter{"extraFilter", "(o2::aod::track::phi < ncfg(float,2.0,phiUp)) && (o2::aod::track::phi > ncfg(float,1.0,phiLow))", "extra filter string"}; + Filter extraF; -struct ConsumeExtendedTables { - void process(aod::Collision const&, soa::Join const& tracks) + void init(InitContext&) { - for (auto& track : tracks) { - LOGF(info, "%.3f == %.3f", track.cosphi(), std::cos(track.phi())); + if (!extraFilter->empty()) { + // string-based filters need to be assigned in init() + extraF = Parser::parse(extraFilter); } } -}; -// tracks which are not tracklets -struct FilterTracks { - Filter notTracklet = aod::track::trackType != static_cast(aod::track::TrackTypeEnum::Run2Tracklet); - void process(aod::Collision const&, soa::Filtered const& tracks) + // process only collisions and tracks which pass all defined filter criteria + void process(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks) { - for (auto& track : tracks) { - LOGF(info, "%.3f == %.3f", track.spt(), std::abs(track.sigma1Pt() / track.signed1Pt())); + LOGF(info, "Collision: %d [N = %d out of %d], -%.1f < %.3f < %.1f", + collision.globalIndex(), tracks.size(), tracks.tableSize(), (float)vtxZ, collision.posZ(), (float)vtxZ); + for (auto const& track : tracks) { + LOGP(info, "id = {}; eta: {} < {} < {}; phi: {} < {} < {}; pt: {} < {} < {}", + track.collisionId(), (float)etaLow, track.eta(), (float)etaUp, (float)phiLow, track.phi(), (float)phiUp, (float)ptLow, track.pt(), (float)ptUp); } } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; + return {adaptAnalysisTask(cfgc)}; }