From b13cff50ee3e5fd901949a64d32e5b3ef2cbada7 Mon Sep 17 00:00:00 2001 From: maciacco Date: Wed, 17 Jan 2024 19:03:29 +0100 Subject: [PATCH 1/3] add task to study antideuteron-lambda fluctuations --- PWGLF/Tasks/CMakeLists.txt | 5 + PWGLF/Tasks/antidLambdaEbye.cxx | 334 ++++++++++++++++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 PWGLF/Tasks/antidLambdaEbye.cxx diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 74dafa9618b..7e92daafeec 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -63,6 +63,11 @@ o2physics_add_dpl_workflow(hyhefour-analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(antid-lambda-ebye + SOURCES antidLambdaEbye.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + # Spectra o2physics_add_dpl_workflow(mc-spectra-efficiency SOURCES mcspectraefficiency.cxx diff --git a/PWGLF/Tasks/antidLambdaEbye.cxx b/PWGLF/Tasks/antidLambdaEbye.cxx new file mode 100644 index 00000000000..6ae0209555c --- /dev/null +++ b/PWGLF/Tasks/antidLambdaEbye.cxx @@ -0,0 +1,334 @@ +// 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. + +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "CCDB/BasicCCDBManager.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/PIDResponse.h" + +#include "TDatabasePDG.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TracksFull = soa::Join; + +namespace +{ +const float lambdaMassPDG = TDatabasePDG::Instance()->GetParticle(3122)->Mass(); +} + +struct antidLambdaEbye { + Service ccdb; + + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; + + ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; + ConfigurableAxis massLambdaAxis{"massLambdaAxis", {400, lambdaMassPDG - 0.03f, lambdaMassPDG + 0.03f}, "binning for the lambda invariant-mass"}; + ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; + + ConfigurableAxis cosPaAxis{"cosPaAxis", {1e3, 0.95f, 1.00f}, "binning for the cosPa axis"}; + ConfigurableAxis radiusAxis{"radiusAxis", {1e3, 0.f, 100.f}, "binning for the radius axis"}; + ConfigurableAxis dcaV0daughAxis{"dcaV0daughAxis", {2e2, 0.f, 2.f}, "binning for the dca of V0 daughters"}; + ConfigurableAxis dcaDaughPvAxis{"dcaDaughPvAxis", {1e3, 0.f, 10.f}, "binning for the dca of positive daughter to PV"}; + + ConfigurableAxis tpcNsigmaAxis{"tpcNsigmaAxis", {100, -5.f, 5.f}, "tpc nsigma axis"}; + ConfigurableAxis tofNsigmaAxis{"tofNsigmaAxis", {100, -5.f, 5.f}, "tof nsigma axis"}; + + // CCDB options + Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; + 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 geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable pidPath{"pidPath", "", "Path to the PID response object"}; + + Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + + Configurable antidPtMin{"antidPtMin", 0.8f, "minimum antideuteron pT (GeV/c)"}; + Configurable antidPtTof{"antidPtTof", 1.0f, "antideuteron pT to switch to TOF pid (GeV/c) "}; + Configurable antidPtMax{"antidPtMax", 1.8f, "maximum antideuteron pT (GeV/c)"}; + + Configurable lambdaPtMin{"lambdaPtMin", 0.5f, "minimum (anti)lambda pT (GeV/c)"}; + Configurable lambdaPtMax{"lambdaPtMax", 3.0f, "maximum (anti)lambda pT (GeV/c)"}; + + Configurable antidNclusItsCut{"antidNclusITScut", 5, "Minimum number of ITS clusters"}; + Configurable antidNclusTpcCut{"antidNclusTPCcut", 70, "Minimum number of TPC clusters"}; + Configurable antidNsigmaTpcCut{"antidNsigmaTpcCut", 4.f, "TPC PID cut"}; + Configurable antidNsigmaTofCut{"antidNsigmaTofCut", 4.f, "TOF PID cut"}; + Configurable antidDcaCut{"antidDcaCut", 0.1f, "DCA antid to PV"}; + + Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"}; + Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1f, "DCA Pos To PV"}; + Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1f, "DCA Neg To PV"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.98, "V0 CosPA"}; + Configurable v0setting_radius{"v0setting_radius", 0.5f, "v0radius"}; + Configurable lambdaMassCut{"lambdaMassCut", 0.005f, "maximum deviation from PDG mass"}; + + int mRunNumber; + float d_bz; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Filter preFilterV0 = (nabs(aod::v0data::dcapostopv) > v0setting_dcapostopv && + nabs(aod::v0data::dcanegtopv) > v0setting_dcanegtopv && + aod::v0data::dcaV0daughters < v0setting_dcav0dau); + + template + bool selectLambda(RecV0 const& v0) // TODO: apply ML + { + if (std::abs(v0.eta()) > etaMax || + v0.v0cosPA() < v0setting_cospa || + v0.v0radius() < v0setting_radius) { + return false; + } + auto mLambda = v0.alpha() > 0 ? v0.mLambda() : v0.mAntiLambda(); + if (std::abs(mLambda - lambdaMassPDG) > lambdaMassCut) { + return false; + } + return true; + } + + template + bool selectAntid(T const& track) + { + if (std::abs(track.eta()) > etaMax) { + return false; + } + if (track.sign() > 0.) { + return false; + } + if (track.itsNCls() < antidNclusItsCut || + track.tpcNClsFound() < antidNclusTpcCut || + track.tpcNClsCrossedRows() < 70 || + track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || + track.tpcChi2NCl() > 4.f || + track.itsChi2NCl() > 36.f || + !(track.trackType() & o2::aod::track::TPCrefit) || + !(track.trackType() & o2::aod::track::ITSrefit)) { + return false; + } + return true; + } + + void init(o2::framework::InitContext&) + { + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + mRunNumber = 0; + d_bz = 0; + + histos.add("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); + + histos.add("nEv", ";#it{N}_{ev};Entries", {HistType::kTH1D}, {centAxis}); + + histos.add("q1antid", ";Centrality (%);#it{q}_{1}(#bar{d})", {HistType::kTH1D}, {centAxis}); + histos.add("q1sqantid", ";Centrality (%);#it{q}_{1}^{2}(#bar{d})", {HistType::kTH1D}, {centAxis}); + histos.add("q2antid", ";Centrality (%);#it{q}_{2}(#bar{d})", {HistType::kTH1D}, {centAxis}); + + histos.add("q1antiL", ";Centrality (%);#it{q}_{1}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis}); + histos.add("q1sqantiL", ";Centrality (%);#it{q}_{1}^{2}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis}); + histos.add("q2antiL", ";Centrality (%);#it{q}_{2}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis}); + + histos.add("q1L", ";Centrality (%);#it{q}_{1}(#Lambda)", {HistType::kTH1D}, {centAxis}); + histos.add("q1sqL", ";Centrality (%);#it{q}_{1}^{2}(#Lambda)", {HistType::kTH1D}, {centAxis}); + histos.add("q2L", ";Centrality (%);#it{q}_{2}(#Lambda)", {HistType::kTH1D}, {centAxis}); + + histos.add("q11Lantid", ";Centrality (%);#it{q}_{11}(#Lambda, #bar{d})", {HistType::kTH1D}, {centAxis}); + histos.add("q11antiLantid", ";Centrality (%);#it{q}_{11}(#bar{#Lambda}, #bar{d})", {HistType::kTH1D}, {centAxis}); + + // v0 QA + histos.add("massLambda", ";#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", {HistType::kTH1F, {massLambdaAxis}}); + histos.add("cosPa", ";cosPa;Entries", {HistType::kTH1F}, {cosPaAxis}); + histos.add("radius", ";radius;Entries", {HistType::kTH1F}, {radiusAxis}); + histos.add("dcaV0daugh", ";dcaV0daugh;Entries", {HistType::kTH1F}, {dcaV0daughAxis}); + histos.add("dcaPosPv", ";dcaPosPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis}); + histos.add("dcaNegPv", ";dcaNegPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis}); + + // v0 QA + histos.add("tpcNsigma", ";tpcNsigma;Entries", {HistType::kTH1F, {tpcNsigmaAxis}}); + histos.add("tofNsigma", ";tofNsigma;Entries", {HistType::kTH1F}, {tofNsigmaAxis}); + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + auto run3grp_timestamp = bc.timestamp(); + + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + if (d_bz_input < -990) { + // 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 { + d_bz = d_bz_input; + } + } 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); + if (d_bz_input < -990) { + // 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"; + } else { + d_bz = d_bz_input; + } + } + mRunNumber = bc.runNumber(); + } + + void process(soa::Join::iterator const& collision, TracksFull const& tracks, soa::Filtered const& V0s, aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + initCCDB(bc); + + if (!collision.sel8()) + return; + + if (std::abs(collision.posZ()) > zVtxMax) + return; + + const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; + + histos.fill(HIST("zVtx"), collision.posZ()); + + double q1antid{0.}, q2antid{0.}; + for (const auto& track : tracks) { + if (!selectAntid(track)) { + continue; + } + + auto trackParCov = getTrackParCov(track); + gpu::gpustd::array dcaInfo; + o2::base::Propagator::Instance()->propagateToDCABxByBz(collVtx, trackParCov, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfo); + + float dcaXYZ = dcaInfo[0]; + if (std::abs(dcaXYZ) > antidDcaCut) { + continue; + } + + if (trackParCov.getPt() < antidPtMin || trackParCov.getPt() > antidPtMax) { + continue; + } + if (std::abs(track.tpcNSigmaDe()) > antidNsigmaTpcCut) { + continue; + } + if (std::abs(track.tofNSigmaDe()) > antidNsigmaTofCut && trackParCov.getPt() > antidPtTof) { + continue; + } + + histos.fill(HIST("tpcNsigma"), track.tpcNSigmaDe()); + if (trackParCov.getPt() > antidPtTof) { + histos.fill(HIST("tofNsigma"), track.tofNSigmaDe()); + } + + q1antid += 1.; // TODO: correct for efficiency + q2antid += 1.; + } + + double q1L{0.}, q2L{0.}, q1antiL{0.}, q2antiL{0.}; + std::vector trkId; + for (const auto& v0 : V0s) { + if (v0.pt() < lambdaPtMin || v0.pt() > lambdaPtMax) { + continue; + } + + if (!selectLambda(v0)) { + continue; + } + + auto pos = v0.template posTrack_as(); + auto neg = v0.template negTrack_as(); + if (std::abs(pos.eta()) > etaMax || std::abs(pos.eta()) > etaMax) { + continue; + } + + bool matter = v0.alpha() > 0; + + histos.fill(HIST("massLambda"), matter ? v0.mLambda() : v0.mAntiLambda()); + histos.fill(HIST("cosPa"), v0.v0cosPA()); + histos.fill(HIST("radius"), v0.v0radius()); + histos.fill(HIST("dcaV0daugh"), v0.dcaV0daughters()); + histos.fill(HIST("dcaPosPv"), v0.dcapostopv()); + histos.fill(HIST("dcaNegPv"), v0.dcanegtopv()); + + if (matter) { + q1L += 1.; // TODO: correct for efficiency + q2L += 1.; + } + else { + q1antiL += 1.; // TODO: correct for efficiency + q2antiL += 1.; + } + + trkId.emplace_back(pos.globalIndex()); + trkId.emplace_back(neg.globalIndex()); + } + + // reject events having multiple v0s from same tracks (TODO: also across collisions?) + std::sort(trkId.begin(), trkId.end()); + if (std::adjacent_find(trkId.begin(), trkId.end()) != trkId.end()) { + return; + } + + histos.fill(HIST("nEv"), collision.centFT0C()); + + histos.fill(HIST("q1antid"), collision.centFT0C(), q1antid); + histos.fill(HIST("q1sqantid"), collision.centFT0C(), std::pow(q1antid, 2)); + histos.fill(HIST("q2antid"), collision.centFT0C(), q2antid); + + histos.fill(HIST("q1L"), collision.centFT0C(), q1L); + histos.fill(HIST("q1sqL"), collision.centFT0C(), std::pow(q1L, 2)); + histos.fill(HIST("q2L"), collision.centFT0C(), q2L); + + histos.fill(HIST("q1antiL"), collision.centFT0C(), q1antiL); + histos.fill(HIST("q1sqantiL"), collision.centFT0C(), std::pow(q1antiL, 2)); + histos.fill(HIST("q2antiL"), collision.centFT0C(), q2antiL); + + histos.fill(HIST("q11Lantid"), collision.centFT0C(), q1L * q1antid); + histos.fill(HIST("q11antiLantid"), collision.centFT0C(), q1antiL * q1antid); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} \ No newline at end of file From 58f9bb007b882e90c5f69c066ea10313511c18fe Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Wed, 17 Jan 2024 18:07:25 +0000 Subject: [PATCH 2/3] Please consider the following formatting changes --- PWGLF/Tasks/antidLambdaEbye.cxx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/antidLambdaEbye.cxx b/PWGLF/Tasks/antidLambdaEbye.cxx index 6ae0209555c..05bd69bbad7 100644 --- a/PWGLF/Tasks/antidLambdaEbye.cxx +++ b/PWGLF/Tasks/antidLambdaEbye.cxx @@ -132,8 +132,8 @@ struct antidLambdaEbye { track.itsChi2NCl() > 36.f || !(track.trackType() & o2::aod::track::TPCrefit) || !(track.trackType() & o2::aod::track::ITSrefit)) { - return false; - } + return false; + } return true; } @@ -220,10 +220,10 @@ struct antidLambdaEbye { initCCDB(bc); if (!collision.sel8()) - return; + return; if (std::abs(collision.posZ()) > zVtxMax) - return; + return; const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; @@ -292,8 +292,7 @@ struct antidLambdaEbye { if (matter) { q1L += 1.; // TODO: correct for efficiency q2L += 1.; - } - else { + } else { q1antiL += 1.; // TODO: correct for efficiency q2antiL += 1.; } From 5ecbb3ee66a7838debd381109287b60cd3a97056 Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Wed, 17 Jan 2024 21:17:16 +0100 Subject: [PATCH 3/3] add empty newline --- PWGLF/Tasks/antidLambdaEbye.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/antidLambdaEbye.cxx b/PWGLF/Tasks/antidLambdaEbye.cxx index 05bd69bbad7..f5dd1f04b74 100644 --- a/PWGLF/Tasks/antidLambdaEbye.cxx +++ b/PWGLF/Tasks/antidLambdaEbye.cxx @@ -330,4 +330,4 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ adaptAnalysisTask(cfgc)}; -} \ No newline at end of file +}