diff --git a/ALICE3/TableProducer/alice3-multicharm.cxx b/ALICE3/TableProducer/alice3-multicharm.cxx index 7b40e01cd20..f695224b7c5 100644 --- a/ALICE3/TableProducer/alice3-multicharm.cxx +++ b/ALICE3/TableProducer/alice3-multicharm.cxx @@ -51,6 +51,7 @@ #include "ALICE3/DataModel/tracksAlice3.h" #include "DetectorsVertexing/PVertexer.h" #include "DetectorsVertexing/PVertexerHelpers.h" +#include "CommonConstants/PhysicsConstants.h" using namespace o2; using namespace o2::framework; @@ -77,19 +78,27 @@ struct alice3multicharm { Produces multiCharmCore; // Operation and minimisation criteria + Configurable fillDerivedTable{"fillDerivedTable", false, "fill MCharm[] tables (careful: memory)"}; Configurable magneticField{"magneticField", 20.0f, "Magnetic field (in kilogauss)"}; Configurable doDCAplots{"doDCAplots", true, "do daughter prong DCA plots for D mesons"}; Configurable mcSameMotherCheck{"mcSameMotherCheck", true, "check if tracks come from the same MC mother"}; - Configurable dcaXiCDaughtersSelection{"dcaXiCDaughtersSelection", 1000.0f, "DCA between XiC daughters (cm)"}; - Configurable dcaXiCCDaughtersSelection{"dcaXiCCDaughtersSelection", 1000.0f, "DCA between XiCC daughters (cm)"}; + Configurable dcaXiCDaughtersSelection{"dcaXiCDaughtersSelection", 200.0f, "DCA between XiC daughters (cm)"}; + Configurable dcaXiCCDaughtersSelection{"dcaXiCCDaughtersSelection", 200.0f, "DCA between XiCC daughters (cm)"}; - Configurable piFromXiC_dcaXYconstant{"piFromXiC_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable piFromXiC_dcaXYconstant{"piFromXiC_dcaXYconstant", 0.001f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromXiC_dcaXYpTdep{"piFromXiC_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; - Configurable piFromXiCC_dcaXYconstant{"piFromXiCC_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable piFromXiCC_dcaXYconstant{"piFromXiCC_dcaXYconstant", 0.001f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromXiCC_dcaXYpTdep{"piFromXiCC_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; - Configurable xiFromXiC_dcaXYconstant{"xiFromXiC_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable xiFromXiC_dcaXYconstant{"xiFromXiC_dcaXYconstant", 0.001f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable xiFromXiC_dcaXYpTdep{"xiFromXiC_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; + Configurable minPiCPt{"minPiCPt", 0.15, "Minimum pT for XiC pions"}; + Configurable minPiCCPt{"minPiCCPt", 0.3, "Minimum pT for XiCC pions"}; + + Configurable minXiCRadius{"minXiCRadius", 0.001, "Minimum R2D for XiC decay (cm)"}; + Configurable massWindowXi{"massWindowXi", 0.015, "Mass window around Xi peak"}; + Configurable massWindowXiC{"massWindowXiC", 0.015, "Mass window around XiC peak"}; + ConfigurableAxis axisEta{"axisEta", {80, -4.0f, +4.0f}, "#eta"}; 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}, "pt axis for QA histograms"}; ConfigurableAxis axisDCA{"axisDCA", {200, -100, 100}, "DCA (#mum)"}; @@ -118,9 +127,9 @@ struct alice3multicharm { // partitions for Xi daughters Partition tracksPiFromXiC = - ((aod::a3DecayMap::decayMap & trackSelectionPiFromXiC) == trackSelectionPiFromXiC) && aod::track::signed1Pt > 0.0f && nabs(aod::track::dcaXY) > piFromXiC_dcaXYconstant + piFromXiC_dcaXYpTdep* nabs(aod::track::signed1Pt); + ((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); Partition tracksPiFromXiCC = - ((aod::a3DecayMap::decayMap & trackSelectionPiFromXiCC) == trackSelectionPiFromXiCC) && aod::track::signed1Pt > 0.0f && nabs(aod::track::dcaXY) > piFromXiCC_dcaXYconstant + piFromXiCC_dcaXYpTdep* nabs(aod::track::signed1Pt); + ((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); // Helper struct to pass candidate information struct { @@ -307,6 +316,33 @@ struct alice3multicharm { return returnValue; } + // Association check for the XiCC pion + template + bool checkSameMotherExtra(TTrackType1 const& track1, TTrackType2 const& track2) + { + bool returnValue = false; + // This might perhaps be a bit excessive + // Could be joined with `checkSameMother` but leaving as is for now + if (track1.has_mcParticle() && track2.has_mcParticle()) { + auto mcParticle1 = track1.template mcParticle_as(); + auto mcParticle2 = track2.template mcParticle_as(); + if (mcParticle1.has_mothers() && mcParticle2.has_mothers()) { + for (auto& mcParticleMother1 : mcParticle1.template mothers_as()) { + if (mcParticleMother1.has_mothers()) { + for (auto& mcParticleGrandMother1 : mcParticleMother1.template mothers_as()) { + for (auto& mcParticleMother2 : mcParticle2.template mothers_as()) { + if (mcParticleGrandMother1.globalIndex() == mcParticleMother2.globalIndex()) { + returnValue = true; + } + } + } + } + } + } + } // end association check + return returnValue; + } + void init(InitContext&) { // initialize O2 2-prong fitter (only once) @@ -336,33 +372,34 @@ struct alice3multicharm { // failure rates. // --- 0: attempt XiC, 1: success XiC // --- 2: attempt XiCC, 3: success XiCC - histos.add("hCharmBuilding", "hCharmBuilding", kTH1F, {{10, -0.5, 9.5f}}); + histos.add("hCharmBuilding", "hCharmBuilding", kTH1D, {{10, -0.5, 9.5f}}); - histos.add("h2dGenXi", "h2dGenXi", kTH2F, {axisPt, axisEta}); - histos.add("h2dGenXiC", "h2dGenXiC", kTH2F, {axisPt, axisEta}); - histos.add("h2dGenXiCC", "h2dGenXiCC", kTH2F, {axisPt, axisEta}); + histos.add("h2dGenXi", "h2dGenXi", kTH2D, {axisPt, axisEta}); + histos.add("h2dGenXiC", "h2dGenXiC", kTH2D, {axisPt, axisEta}); + histos.add("h2dGenXiCC", "h2dGenXiCC", kTH2D, {axisPt, axisEta}); - histos.add("hMassXi", "hMassXi", kTH1F, {axisXiMass}); - histos.add("hMassXiC", "hMassXiC", kTH1F, {axisXiCMass}); - histos.add("hMassXiCC", "hMassXiCC", kTH1F, {axisXiCCMass}); + histos.add("hMassXi", "hMassXi", kTH1D, {axisXiMass}); + histos.add("hMassXiC", "hMassXiC", kTH1D, {axisXiCMass}); + histos.add("hMassXiCC", "hMassXiCC", kTH1D, {axisXiCCMass}); - histos.add("hEtaXiCC", "hEtaXiCC", kTH1F, {axisEta}); - histos.add("hPtXiCC", "hPtXiCC", kTH1F, {axisPt}); - histos.add("h3dMassXiCC", "h3dMassXiCC", kTH3F, {axisPt, axisEta, axisXiCCMass}); + histos.add("hEtaXiCC", "hEtaXiCC", kTH1D, {axisEta}); + histos.add("hPtXiCC", "hPtXiCC", kTH1D, {axisPt}); + histos.add("hMcPtXiCC", "hMcPtXiCC", kTH1D, {axisPt}); + histos.add("h3dMassXiCC", "h3dMassXiCC", kTH3D, {axisPt, axisEta, axisXiCCMass}); - histos.add("hDCAXiCDaughters", "hDCAXiCDaughters", kTH1F, {axisDCAXiCDaughters}); - histos.add("hDCAXiCCDaughters", "hDCAXiCCDaughters", kTH1F, {axisDCAXiCCDaughters}); + histos.add("hDCAXiCDaughters", "hDCAXiCDaughters", kTH1D, {axisDCAXiCDaughters}); + histos.add("hDCAXiCCDaughters", "hDCAXiCCDaughters", kTH1D, {axisDCAXiCCDaughters}); // These histograms bookkeep the exact number of combinations attempted // CombinationsXiC: triplets Xi-pi-pi considered per Xi // CombinationsXiCC: doublets XiC-pi considered per XiC - histos.add("hCombinationsXiC", "hCombinationsXiC", kTH1F, {axisNConsidered}); - histos.add("hCombinationsXiCC", "hCombinationsXiCC", kTH1F, {axisNConsidered}); + histos.add("hCombinationsXiC", "hCombinationsXiC", kTH1D, {axisNConsidered}); + histos.add("hCombinationsXiCC", "hCombinationsXiCC", kTH1D, {axisNConsidered}); if (doDCAplots) { - histos.add("h2dDCAxyVsPtXiFromXiC", "h2dDCAxyVsPtXiFromXiC", kTH2F, {axisPt, axisDCA}); - histos.add("h2dDCAxyVsPtPiFromXiC", "h2dDCAxyVsPtPiFromXiC", kTH2F, {axisPt, axisDCA}); - histos.add("h2dDCAxyVsPtPiFromXiCC", "h2dDCAxyVsPtPiFromXiCC", kTH2F, {axisPt, axisDCA}); + histos.add("h2dDCAxyVsPtXiFromXiC", "h2dDCAxyVsPtXiFromXiC", kTH2D, {axisPt, axisDCA}); + histos.add("h2dDCAxyVsPtPiFromXiC", "h2dDCAxyVsPtPiFromXiC", kTH2D, {axisPt, axisDCA}); + histos.add("h2dDCAxyVsPtPiFromXiCC", "h2dDCAxyVsPtPiFromXiCC", kTH2D, {axisPt, axisDCA}); } } @@ -373,8 +410,10 @@ struct alice3multicharm { histos.fill(HIST("h2dGenXi"), mcParticle.pt(), mcParticle.eta()); for (auto const& mcParticle : trueXiC) histos.fill(HIST("h2dGenXiC"), mcParticle.pt(), mcParticle.eta()); - for (auto const& mcParticle : trueXiCC) + for (auto const& mcParticle : trueXiCC) { histos.fill(HIST("h2dGenXiCC"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("hMcPtXiCC"), mcParticle.pt()); + } } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -404,6 +443,10 @@ struct alice3multicharm { for (auto const& xiCand : cascades) { histos.fill(HIST("hMassXi"), xiCand.mXi()); + + if (std::abs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > massWindowXi) + continue; // out of mass region + uint32_t nCombinationsC = 0; auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track auto piFromXi = xiCand.bachTrack_as(); // de-reference bach track @@ -418,6 +461,8 @@ struct alice3multicharm { continue; if (xiCand.posTrackId() == pi1c.globalIndex() || xiCand.negTrackId() == pi1c.globalIndex() || xiCand.bachTrackId() == pi1c.globalIndex()) continue; // avoid using any track that was already used + if (pi1c.pt() < minPiCPt) + continue; // second pion from XiC decay for starts here for (auto const& pi2c : tracksPiFromXiCgrouped) { @@ -428,6 +473,8 @@ struct alice3multicharm { continue; // avoid same-mother, avoid double-counting if (xiCand.posTrackId() == pi2c.globalIndex() || xiCand.negTrackId() == pi2c.globalIndex() || xiCand.bachTrackId() == pi2c.globalIndex()) continue; // avoid using any track that was already used + if (pi2c.pt() < minPiCPt) + continue; // if I am here, it means this is a triplet to be considered for XiC vertexing. // will now attempt to build a three-body decay candidate with these three track rows. @@ -436,6 +483,9 @@ struct alice3multicharm { histos.fill(HIST("hCharmBuilding"), 0.0f); if (!buildDecayCandidateThreeBody(xi, pi1c, pi2c, 1.32171, 0.139570, 0.139570)) continue; // failed at building candidate + + if (std::abs(thisXiCcandidate.mass - o2::constants::physics::MassXiCPlus) > massWindowXiC) + continue; // out of mass region histos.fill(HIST("hCharmBuilding"), 1.0f); const std::array momentumC = { @@ -445,6 +495,9 @@ struct alice3multicharm { o2::track::TrackParCov xicTrack(thisXiCcandidate.xyz, momentumC, thisXiCcandidate.parentTrackCovMatrix, +1); + if (std::hypot(thisXiCcandidate.xyz[0], thisXiCcandidate.xyz[1]) < minXiCRadius) + continue; // do not take if radius too small, likely a primary combination + o2::dataformats::DCA dcaInfo; float xicdcaXY = 1e+10, xicdcaZ = 1e+10; o2::track::TrackParCov xicTrackCopy(xicTrack); // paranoia @@ -466,8 +519,10 @@ struct alice3multicharm { if (xiCand.posTrackId() == picc.globalIndex() || xiCand.negTrackId() == picc.globalIndex() || xiCand.bachTrackId() == picc.globalIndex()) continue; // avoid using any track that was already used - - // to-do: check same mother here + if (picc.pt() < minPiCCPt) + continue; + if (mcSameMotherCheck && !checkSameMotherExtra(xi, picc)) + continue; o2::track::TrackParCov piccTrack = getTrackParCov(picc); nCombinationsCC++; histos.fill(HIST("hCharmBuilding"), 2.0f); @@ -495,18 +550,20 @@ struct alice3multicharm { } // produce multi-charm table for posterior analysis - multiCharmCore( - thisXiCcandidate.dca, thisXiCCcandidate.dca, - thisXiCcandidate.mass, thisXiCCcandidate.mass, - thisXiCCcandidate.pt, thisXiCCcandidate.eta, - xi.nSiliconHits(), piFromXi.nSiliconHits(), - piFromLa.nSiliconHits(), prFromLa.nSiliconHits(), - pi1c.nSiliconHits(), pi2c.nSiliconHits(), picc.nSiliconHits(), - piFromXi.nTPCHits(), piFromLa.nTPCHits(), prFromLa.nTPCHits(), - pi1c.nTPCHits(), pi2c.nTPCHits(), picc.nTPCHits(), - xi.dcaXY(), xicdcaXY, xiccdcaXY, - piFromXi.dcaXY(), piFromLa.dcaXY(), prFromLa.dcaXY(), - pi1c.dcaXY(), pi2c.dcaXY(), picc.dcaXY()); + if (fillDerivedTable) { + multiCharmCore( + thisXiCcandidate.dca, thisXiCCcandidate.dca, + thisXiCcandidate.mass, thisXiCCcandidate.mass, + thisXiCCcandidate.pt, thisXiCCcandidate.eta, + xi.nSiliconHits(), piFromXi.nSiliconHits(), + piFromLa.nSiliconHits(), prFromLa.nSiliconHits(), + pi1c.nSiliconHits(), pi2c.nSiliconHits(), picc.nSiliconHits(), + piFromXi.nTPCHits(), piFromLa.nTPCHits(), prFromLa.nTPCHits(), + pi1c.nTPCHits(), pi2c.nTPCHits(), picc.nTPCHits(), + xi.dcaXY(), xicdcaXY, xiccdcaXY, + piFromXi.dcaXY(), piFromLa.dcaXY(), prFromLa.dcaXY(), + pi1c.dcaXY(), pi2c.dcaXY(), picc.dcaXY()); + } } histos.fill(HIST("hCombinationsXiCC"), nCombinationsCC); } diff --git a/Common/Core/CMakeLists.txt b/Common/Core/CMakeLists.txt index 61ca933740c..babf1a6ccdc 100644 --- a/Common/Core/CMakeLists.txt +++ b/Common/Core/CMakeLists.txt @@ -18,6 +18,7 @@ o2physics_add_library(AnalysisCore EventPlaneHelper.cxx TableHelper.cxx MetadataHelper.cxx + CollisionTypeHelper.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsParameters ROOT::EG O2::CCDB ROOT::Physics O2::FT0Base O2::FV0Base) o2physics_target_root_dictionary(AnalysisCore @@ -31,4 +32,9 @@ o2physics_target_root_dictionary(AnalysisCore PID/DetectorResponse.h PID/PIDTOF.h PID/TPCPIDResponse.h + CollisionTypeHelper.h LINKDEF AnalysisCoreLinkDef.h) + +o2physics_add_header_only_library(TPCDriftManager + HEADERS TPCVDriftManager.h + INTERFACE_LINK_LIBRARIES O2::DataFormatsTPC) diff --git a/Common/Core/CollisionTypeHelper.cxx b/Common/Core/CollisionTypeHelper.cxx new file mode 100644 index 00000000000..c22510ec82e --- /dev/null +++ b/Common/Core/CollisionTypeHelper.cxx @@ -0,0 +1,58 @@ +// 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 CollisionTypeHelper.h +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \brief Utility to handle the collision type from the GRP information +/// + +#include "Common/Core/CollisionTypeHelper.h" +#include +#include +#include "DataFormatsParameters/GRPLHCIFData.h" + +std::string CollisionSystemType::getCollisionSystemName(collType collSys) +{ + switch (collSys) { + case kCollSyspp: + return "pp"; + case kCollSysPbPb: + return "PbPb"; + case kCollSysXeXe: + return "XeXe"; + case kCollSyspPb: + return "pPb"; + default: + return "Undefined"; + } +} + +int CollisionSystemType::getCollisionTypeFromGrp(o2::parameters::GRPLHCIFData* grplhcif) +{ + const int ZBeamA = grplhcif->getBeamZ(o2::constants::lhc::BeamDirection::BeamA); + const int ZBeamC = grplhcif->getBeamZ(o2::constants::lhc::BeamDirection::BeamC); + LOG(debug) << "Collision system: " << ZBeamA << " * " << ZBeamC << " detected"; + switch (ZBeamA * ZBeamC) { + case 1: // pp 1*1 + return kCollSyspp; + case 6724: // Pb-Pb 82*82 + return kCollSysPbPb; + case 225: // Xe-Xe 54*54 + return kCollSysXeXe; + case 82: // p-Pb 82*1 + return kCollSyspPb; + default: + LOG(fatal) << "Undefined collision system in getCollisionTypeFromGrp with BeamA = " << ZBeamA << " and BeamC = " << ZBeamC; + return kCollSysUndef; + } + return kCollSysUndef; +} diff --git a/Common/Core/CollisionTypeHelper.h b/Common/Core/CollisionTypeHelper.h new file mode 100644 index 00000000000..0196fdc03bb --- /dev/null +++ b/Common/Core/CollisionTypeHelper.h @@ -0,0 +1,41 @@ +// 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 CollisionTypeHelper.h +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \brief Utility to handle the collision type from the GRP information +/// + +#ifndef COMMON_CORE_COLLISIONTYPEHELPER_H_ +#define COMMON_CORE_COLLISIONTYPEHELPER_H_ + +#include +#include "DataFormatsParameters/GRPLHCIFData.h" + +// Container for the collision system type +struct CollisionSystemType { + // Enum type for the collision system + typedef int collType; + + static constexpr collType kCollSysUndef = -1; // Undefined collision system + static constexpr collType kCollSyspp = 0; // pp + static constexpr collType kCollSysPbPb = 1; // PbPb + static constexpr collType kCollSysXeXe = 2; // XeXe + static constexpr collType kCollSyspPb = 3; // pPb + static constexpr collType kNCollSys = 4; // Number of collision systems + + static std::string getCollisionSystemName(collType collSys); + + static int getCollisionTypeFromGrp(o2::parameters::GRPLHCIFData* grplhcif); +}; + +#endif // COMMON_CORE_COLLISIONTYPEHELPER_H_ diff --git a/Common/Core/TPCVDriftManager.h b/Common/Core/TPCVDriftManager.h new file mode 100644 index 00000000000..5a3e33bdb2b --- /dev/null +++ b/Common/Core/TPCVDriftManager.h @@ -0,0 +1,165 @@ +// 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. + +#ifndef COMMON_CORE_TPCVDRIFTMANAGER_H_ +#define COMMON_CORE_TPCVDRIFTMANAGER_H_ + +#include + +#include "CCDB/BasicCCDBManager.h" +#include "Framework/Logger.h" +#include "Framework/DataTypes.h" +#include "DataFormatsTPC/VDriftCorrFact.h" +#include "CommonConstants/LHCConstants.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "ReconstructionDataFormats/Track.h" + +namespace o2::aod::common +{ + +// Thin wrapper for vdrift ccdb queries should partially mirror VDriftHelper class. +// Allows to move TPC standalone tracks under the assumption of a different +// collision than the track is associated to. +class TPCVDriftManager +{ + public: + void init(o2::ccdb::BasicCCDBManager* ccdb) noexcept + { + mCCDB = ccdb; + } + + void update(uint64_t timestamp) noexcept + { + // Check validity of already present obj, otherwise update + if (mVD != nullptr && (timestamp > mVD->firstTime || timestamp < mVD->lastTime)) { + return; + } + + // Update Obj + mVD = mCCDB->getForTimeStamp("TPC/Calib/VDriftTgl", timestamp); + if (mVD == nullptr) { + LOGP(error, "Got nullptr from ccdb for VDriftCorrFact for {}", timestamp); + return; + } + + // TODO account for laser calib + + // Update factors + mTPCVDriftNS = mVD->refVDrift * mVD->corrFact * 1e-3; + + LOGP(info, "Updated VDrift for timestamp {} with vdrift={:.7f} (cm/ns)", mVD->creationTime, mTPCVDriftNS); + } + + template + [[nodiscard]] bool moveTPCTrack(const Collision& col, const TrackExtra& trackExtra, Track& track) noexcept + { + ++mCalls; + // track is fine, or cannot be moved has information is not available + if (!(trackExtra.flags() & o2::aod::track::TrackFlags::TrackTimeAsym)) { + ++mNoFlag; + return true; + } + + // Check if there is a good object available otherwise pretend everything is fine + if (mVD == nullptr) { + LOGP(warn, "No VDrift object available, pretending track to be correct"); + ++mNull; + return true; + } + + // FS TODO + // add geometrical check for constrained tracks, e.g., tracks which cross the central pad. + + // TPC time is given relative to the closest BC in ns + float tTB, tTBErr; + if (col.collisionTimeRes() < 0.f) { // use track data + ++mColResNeg; + tTB = trackExtra.trackTime(); + o2::aod::track::extensions::TPCTimeErrEncoding enc; + enc.encoding.timeErr = trackExtra.trackTimeRes(); + tTBErr = 0.5f * (enc.getDeltaTFwd() + enc.getDeltaTBwd()); + } else { + ++mColResPos; + // The TPC track can be associated to a different BC than the one the collision under assumption is; + // we need to calculate the difference and subtract this from the trackTime() + const auto& trackBC = trackExtra.template collision_as().template foundBC_as().globalBC(); + const auto& colBC = col.template foundBC_as().globalBC(); + float sign{1.f}; + uint64_t diffBC{0}; + if (colBC < trackBC) { + sign = 1.f; + diffBC = (trackBC - colBC); + } else { + diffBC = (colBC - trackBC); + } + float diffBCNS = sign * diffBC * o2::constants::lhc::LHCBunchSpacingNS; + tTB = col.collisionTime() + diffBCNS; + tTBErr = col.collisionTimeRes(); + } + float dTime = tTB - trackExtra.trackTime(); + float dDrift = dTime * mTPCVDriftNS; + float dDriftErr = tTBErr * mTPCVDriftNS; + if (dDriftErr < 0.f || dDrift > 250.f) { // we cannot move a track outside the drift volume + if (mOutside < mWarningLimit) { + LOGP(warn, "Skipping correction outside of tpc volume with dDrift={} +- {}", dDrift, dDriftErr); + const auto& trackBC = trackExtra.template collision_as().template foundBC_as().globalBC(); + const auto& colBC = col.template foundBC_as().globalBC(); + int diffBC = colBC - trackBC; + LOGP(info, "ct={}; ctr={}; tTB={}; t0={}; dTime={}; dDrift={}; tgl={}: colBC={} trackBC={} diffBC={}", col.collisionTime(), col.collisionTimeRes(), tTB, trackExtra.trackTime(), dTime, dDrift, track.getTgl(), colBC, trackBC, diffBC); + if (mOutside == mWarningLimit - 1) { + LOGP(warn, "Silencing further warnings!"); + } + } + ++mOutside; + return false; + } + + // impose new Z coordinate + track.setZ(track.getZ() + ((track.getTgl() < 0.) ? -dDrift : dDrift)); + if constexpr (std::is_base_of_v) { + track.setCov(track.getSigmaZ2() + dDriftErr * dDriftErr, o2::track::kSigZ2); + } + + ++mMovedTrks; + + return true; + } + + void print() noexcept + { + LOGP(info, "TPC corrections called: {}; Moved Tracks: {}; Constrained Tracks={}; No Flag: {}; NULL: {}; Outside: {}; ColResPos {}; ColResNeg {};", mCalls, mMovedTrks, mConstrained, mNoFlag, mNull, mOutside, mColResPos, mColResNeg); + } + + private: + // Factors + float mTPCVDriftNS{0.f}; // drift velocity in cm/ns + + // CCDB + const o2::tpc::VDriftCorrFact* mVD{}; // reference to drift correction + o2::ccdb::BasicCCDBManager* mCCDB{}; // reference to initialized ccdb manager + + static constexpr unsigned int mWarningLimit{10}; + + // Counters + unsigned int mCalls{0}; // total number of calls + unsigned int mMovedTrks{0}; // number of moved tracks + unsigned int mNull{0}; // number of tracks where no drift object was available + unsigned int mColResNeg{0}; // number of collisions with negative resolution + unsigned int mColResPos{0}; // number of collisions with positive resolution + unsigned int mNoFlag{0}; // number of tracks without flag set + unsigned int mOutside{0}; // number of tracks moved but outside of sensible volume + unsigned int mConstrained{0}; // number of constrained tracks +}; + +} // namespace o2::aod::common + +#endif // COMMON_CORE_TPCVDRIFTMANAGER_H_ diff --git a/Common/Core/TrackSelection.h b/Common/Core/TrackSelection.h index 618124f638f..351b662c48d 100644 --- a/Common/Core/TrackSelection.h +++ b/Common/Core/TrackSelection.h @@ -195,10 +195,10 @@ class TrackSelection return (isRun2 && mRequireGoldenChi2) ? (track.flags() & o2::aod::track::GoldenChi2) : true; case TrackCuts::kDCAxy: - return abs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); + return std::fabs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); case TrackCuts::kDCAz: - return abs(track.dcaZ()) <= mMaxDcaZ; + return std::fabs(track.dcaZ()) <= mMaxDcaZ; default: return false; diff --git a/Common/DataModel/CMakeLists.txt b/Common/DataModel/CMakeLists.txt index 312e9c15225..f4428d908c0 100644 --- a/Common/DataModel/CMakeLists.txt +++ b/Common/DataModel/CMakeLists.txt @@ -20,4 +20,5 @@ o2physics_add_header_only_library(DataModel TrackSelectionTables.h McCollisionExtra.h Qvectors.h + MatchMFTFT0.h MftmchMatchingML.h) diff --git a/Common/DataModel/MatchMFTFT0.h b/Common/DataModel/MatchMFTFT0.h new file mode 100644 index 00000000000..21ee19b696f --- /dev/null +++ b/Common/DataModel/MatchMFTFT0.h @@ -0,0 +1,34 @@ +// 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 MatchMFTFT0.h +// \author Sarah Herrmann +// +// \brief Declaration of tables useful for the matching of MFT tracks to FT0-C signals +// \date 03/09/24 + +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +namespace indices +{ // For bctoft0c +DECLARE_SOA_ARRAY_INDEX_COLUMN(FT0, ft0s); // has_ft0s works now, without it doesn't +DECLARE_SOA_ARRAY_INDEX_COLUMN(BC, bcs); // has_bcs works now, without it doesn't +} // namespace indices +namespace ambii +{ // for MA2T +DECLARE_SOA_INDEX_COLUMN(MFTTrack, track); +} // namespace ambii +DECLARE_SOA_TABLE(MatchedToFT0, "AOD", "MAFT", indices::BCId, indices::FT0Ids); + +DECLARE_SOA_TABLE(BCofMFT, "AOD", "BCOFMFT", ambii::MFTTrackId, indices::BCIds); +} // namespace o2::aod diff --git a/Common/DataModel/Multiplicity.h b/Common/DataModel/Multiplicity.h index f84169973d0..19ef25b0591 100644 --- a/Common/DataModel/Multiplicity.h +++ b/Common/DataModel/Multiplicity.h @@ -51,6 +51,7 @@ DECLARE_SOA_COLUMN(MultMCFT0C, multMCFT0C, int); //! DECLARE_SOA_COLUMN(MultMCNParticlesEta10, multMCNParticlesEta10, int); //! DECLARE_SOA_COLUMN(MultMCNParticlesEta08, multMCNParticlesEta08, int); //! DECLARE_SOA_COLUMN(MultMCNParticlesEta05, multMCNParticlesEta05, int); //! +DECLARE_SOA_COLUMN(MultMCPVz, multMCPVz, float); //! // complementary / MultsExtra table DECLARE_SOA_COLUMN(MultPVTotalContributors, multPVTotalContributors, int); //! @@ -76,8 +77,6 @@ DECLARE_SOA_COLUMN(MultNGlobalTracksPV, multNGlobalTracksPV, int); DECLARE_SOA_COLUMN(MultNGlobalTracksPVeta1, multNGlobalTracksPVeta1, int); DECLARE_SOA_COLUMN(MultNGlobalTracksPVetaHalf, multNGlobalTracksPVetaHalf, int); -DECLARE_SOA_COLUMN(BCNumber, bcNumber, int); //! - // even further QA: timing information for neighboring events DECLARE_SOA_COLUMN(TimeToPrePrevious, timeToPrePrevious, float); //! DECLARE_SOA_COLUMN(TimeToPrevious, timeToPrevious, float); //! @@ -108,15 +107,15 @@ DECLARE_SOA_TABLE(PVMults, "AOD", "PVMULT", //! Multiplicity from the PV contrib mult::IsInelGt1); using BarrelMults = soa::Join; using Mults = soa::Join; +using FT0Mult = FT0Mults::iterator; using Mult = Mults::iterator; -// for QA purposes DECLARE_SOA_TABLE(MultsExtra, "AOD", "MULTEXTRA", //! mult::MultPVTotalContributors, mult::MultPVChi2, mult::MultCollisionTimeRes, mult::MultRunNumber, mult::MultPVz, mult::MultSel8, mult::MultNTracksHasITS, mult::MultNTracksHasTPC, mult::MultNTracksHasTOF, mult::MultNTracksHasTRD, mult::MultNTracksITSOnly, mult::MultNTracksTPCOnly, mult::MultNTracksITSTPC, mult::MultAllTracksTPCOnly, mult::MultAllTracksITSTPC, - mult::BCNumber, evsel::NumTracksInTimeRange); + evsel::NumTracksInTimeRange); DECLARE_SOA_TABLE(MultNeighs, "AOD", "MULTNEIGH", //! mult::TimeToPrePrevious, mult::TimeToPrevious, @@ -131,16 +130,29 @@ DECLARE_SOA_TABLE(MultsGlobal, "AOD", "MULTGLOBAL", //! counters that use Track DECLARE_SOA_TABLE(MultSelections, "AOD", "MULTSELECTIONS", //! evsel::Selection); // for derived data / QA studies using MultExtra = MultsExtra::iterator; -DECLARE_SOA_TABLE(MultsExtraMC, "AOD", "MULTEXTRAMC", //! Table for the MC information + +// mc collisions table - indexed to Mult +DECLARE_SOA_TABLE(MultMCExtras, "AOD", "MULTMCEXTRA", //! Table for the MC information mult::MultMCFT0A, mult::MultMCFT0C, mult::MultMCNParticlesEta05, mult::MultMCNParticlesEta08, mult::MultMCNParticlesEta10, + mult::MultMCPVz, mult::IsInelGt0, mult::IsInelGt1, o2::soa::Marker<1>); -using MultExtraMC = MultsExtraMC::iterator; +using MultMCExtra = MultMCExtras::iterator; +using MultsExtraMC = MultMCExtras; // for backwards compatibility with previous naming scheme + +// crosslinks +namespace mult +{ +DECLARE_SOA_INDEX_COLUMN(MultMCExtra, multMCExtra); +} + +DECLARE_SOA_TABLE(MC2Mults, "AOD", "MC2MULTS", //! Relate BC -> mult + o2::soa::Index<>, mult::MultMCExtraId); namespace multZeq { @@ -170,12 +182,12 @@ DECLARE_SOA_COLUMN(MultBCFV0A, multBCFV0A, float); //! DECLARE_SOA_COLUMN(MultBCFDDA, multBCFDDA, float); //! DECLARE_SOA_COLUMN(MultBCFDDC, multBCFDDC, float); //! -DECLARE_SOA_COLUMN(MultBCFZNA, multBCFZNA, float); //! -DECLARE_SOA_COLUMN(MultBCFZNC, multBCFZNC, float); //! -DECLARE_SOA_COLUMN(MultBCFZEM1, multBCFZEM1, float); //! -DECLARE_SOA_COLUMN(MultBCFZEM2, multBCFZEM2, float); //! -DECLARE_SOA_COLUMN(MultBCFZPA, multBCFZPA, float); //! -DECLARE_SOA_COLUMN(MultBCFZPC, multBCFZPC, float); //! +DECLARE_SOA_COLUMN(MultBCZNA, multBCZNA, float); //! +DECLARE_SOA_COLUMN(MultBCZNC, multBCZNC, float); //! +DECLARE_SOA_COLUMN(MultBCZEM1, multBCZEM1, float); //! +DECLARE_SOA_COLUMN(MultBCZEM2, multBCZEM2, float); //! +DECLARE_SOA_COLUMN(MultBCZPA, multBCZPA, float); //! +DECLARE_SOA_COLUMN(MultBCZPC, multBCZPC, float); //! DECLARE_SOA_COLUMN(MultBCTVX, multBCTVX, bool); //! DECLARE_SOA_COLUMN(MultBCFV0OrA, multBCFV0OrA, bool); //! @@ -184,19 +196,25 @@ DECLARE_SOA_COLUMN(MultBCT0triggerBits, multBCT0triggerBits, uint8_t); //! DECLARE_SOA_COLUMN(MultBCFDDtriggerBits, multBCFDDtriggerBits, uint8_t); //! DECLARE_SOA_COLUMN(MultBCTriggerMask, multBCTriggerMask, uint64_t); //! CTP trigger mask DECLARE_SOA_COLUMN(MultBCColliding, multBCColliding, bool); //! CTP trigger mask + +DECLARE_SOA_COLUMN(MultBCFT0PosZ, multBCFT0PosZ, float); //! Position along Z computed with the FT0 information within the BC +DECLARE_SOA_COLUMN(MultBCFT0PosZValid, multBCFT0PosZValid, bool); //! Validity of the position along Z computed with the FT0 information within the BC + } // namespace multBC -DECLARE_SOA_TABLE(MultsBC, "AOD", "MULTBC", //! +DECLARE_SOA_TABLE(MultBCs, "AOD", "MULTBC", //! multBC::MultBCFT0A, multBC::MultBCFT0C, + multBC::MultBCFT0PosZ, + multBC::MultBCFT0PosZValid, multBC::MultBCFV0A, multBC::MultBCFDDA, multBC::MultBCFDDC, - multBC::MultBCFZNA, - multBC::MultBCFZNC, - multBC::MultBCFZEM1, - multBC::MultBCFZEM2, - multBC::MultBCFZPA, - multBC::MultBCFZPC, + multBC::MultBCZNA, + multBC::MultBCZNC, + multBC::MultBCZEM1, + multBC::MultBCZEM2, + multBC::MultBCZPA, + multBC::MultBCZPC, multBC::MultBCTVX, multBC::MultBCFV0OrA, multBC::MultBCV0triggerBits, @@ -204,7 +222,23 @@ DECLARE_SOA_TABLE(MultsBC, "AOD", "MULTBC", //! multBC::MultBCFDDtriggerBits, multBC::MultBCTriggerMask, multBC::MultBCColliding); -using MultBC = MultsBC::iterator; +using MultBC = MultBCs::iterator; + +// crosslinks +namespace mult +{ +DECLARE_SOA_INDEX_COLUMN(MultBC, multBC); +} +namespace multBC +{ +DECLARE_SOA_INDEX_COLUMN(FT0Mult, ft0Mult); +} + +// for QA purposes +DECLARE_SOA_TABLE(Mults2BC, "AOD", "MULTS2BC", //! Relate mult -> BC + o2::soa::Index<>, mult::MultBCId); +DECLARE_SOA_TABLE(BC2Mults, "AOD", "BC2MULTS", //! Relate BC -> mult + o2::soa::Index<>, multBC::FT0MultId); } // namespace o2::aod diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 7cd53628f18..399ba4b4fa6 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -112,3 +112,10 @@ o2physics_add_dpl_workflow(mftmchmatchingml O2::CCDB O2Physics::MLCore O2::ReconstructionDataFormats COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(match-mft-ft0 + SOURCES match-mft-ft0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + O2::ReconstructionDataFormats + O2::DetectorsBase O2::DetectorsCommonDataFormats + COMPONENT_NAME Analysis) diff --git a/Common/TableProducer/PID/pidTOFMerge.cxx b/Common/TableProducer/PID/pidTOFMerge.cxx index 51343f328cb..68bd490f041 100644 --- a/Common/TableProducer/PID/pidTOFMerge.cxx +++ b/Common/TableProducer/PID/pidTOFMerge.cxx @@ -31,6 +31,7 @@ // O2Physics includes #include "TableHelper.h" #include "MetadataHelper.h" +#include "CollisionTypeHelper.h" #include "pidTOFBase.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" @@ -45,125 +46,219 @@ using namespace o2::track; MetadataHelper metadataInfo; +// Input data types +using Run3Trks = o2::soa::Join; +using Run3Cols = aod::Collisions; +using Run3TrksWtof = soa::Join; +using Run3TrksWtofWevTime = soa::Join; + +using EvTimeCollisions = soa::Join; +using EvTimeCollisionsFT0 = soa::Join; + +using Run2Trks = o2::soa::Join; +using Run2TrksWtofWevTime = soa::Join; + // Configuration common to all tasks -struct TOFCalibConfig : ConfigurableGroup { - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; - Configurable timeShiftCCDBPath{"timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; - Configurable paramFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; - Configurable parametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; - Configurable passName{"passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; - Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; - Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; - - void inheritFromBaseTask(o2::framework::InitContext& initContext) +struct TOFCalibConfig { + template + void init(const CfgType& opt) { - if (!getTaskOptionValue(initContext, "tof-signal", "ccdb-url", url.value, true)) { - LOG(fatal) << "Could not get ccdb-url from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "ccdb-timestamp", timestamp.value, true)) { - LOG(fatal) << "Could not get ccdb-timestamp from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "paramFileName", paramFileName.value, true)) { - LOG(fatal) << "Could not get paramFileName from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "parametrizationPath", parametrizationPath.value, true)) { - LOG(fatal) << "Could not get parametrizationPath from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "passName", passName.value, true)) { - LOG(fatal) << "Could not get passName from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "timeShiftCCDBPath", timeShiftCCDBPath.value, true)) { - LOG(fatal) << "Could not get timeShiftCCDBPath from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "loadResponseFromCCDB", loadResponseFromCCDB.value, true)) { - LOG(fatal) << "Could not get loadResponseFromCCDB from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "fatalOnPassNotAvailable", fatalOnPassNotAvailable.value, true)) { - LOG(fatal) << "Could not get fatalOnPassNotAvailable from tof-signal task"; + mUrl = opt.cfgUrl.value; + mPathGrpLhcIf = opt.cfgPathGrpLhcIf.value; + mTimestamp = opt.cfgTimestamp.value; + mTimeShiftCCDBPathPos = opt.cfgTimeShiftCCDBPathPos.value; + mTimeShiftCCDBPathNeg = opt.cfgTimeShiftCCDBPathNeg.value; + mParamFileName = opt.cfgParamFileName.value; + mParametrizationPath = opt.cfgParametrizationPath.value; + mReconstructionPass = opt.cfgReconstructionPass.value; + mLoadResponseFromCCDB = opt.cfgLoadResponseFromCCDB.value; + mFatalOnPassNotAvailable = opt.cfgFatalOnPassNotAvailable.value; + mEnableTimeDependentResponse = opt.cfgEnableTimeDependentResponse.value; + mCollisionSystem = opt.cfgCollisionSystem.value; + mAutoSetProcessFunctions = opt.cfgAutoSetProcessFunctions.value; + } + + template + void getCfg(o2::framework::InitContext& initContext, const std::string name, VType& v, const std::string task) + { + if (!getTaskOptionValue(initContext, task, name, v, true)) { + LOG(fatal) << "Could not get " << name << " from " << task << " task"; } } + void inheritFromBaseTask(o2::framework::InitContext& initContext, const std::string task = "tof-signal") + { + mInitMode = 2; + getCfg(initContext, "ccdb-url", mUrl, task); + getCfg(initContext, "ccdb-path-grplhcif", mPathGrpLhcIf, task); + getCfg(initContext, "ccdb-timestamp", mTimestamp, task); + getCfg(initContext, "timeShiftCCDBPathPos", mTimeShiftCCDBPathPos, task); + getCfg(initContext, "timeShiftCCDBPathNeg", mTimeShiftCCDBPathPos, task); + getCfg(initContext, "paramFileName", mParamFileName, task); + getCfg(initContext, "parametrizationPath", mParametrizationPath, task); + getCfg(initContext, "reconstructionPass", mReconstructionPass, task); + getCfg(initContext, "loadResponseFromCCDB", mLoadResponseFromCCDB, task); + getCfg(initContext, "fatalOnPassNotAvailable", mFatalOnPassNotAvailable, task); + getCfg(initContext, "enableTimeDependentResponse", mEnableTimeDependentResponse, task); + getCfg(initContext, "collisionSystem", mCollisionSystem, task); + getCfg(initContext, "autoSetProcessFunctions", mAutoSetProcessFunctions, task); + } + // @brief Set up the configuration from the calibration object from the init function of the task template - void setUp(o2::pid::tof::TOFResoParamsV3& mRespParamsV3, CCDBObject ccdb) + void initSetup(o2::pid::tof::TOFResoParamsV3& mRespParamsV3, + CCDBObject ccdb) { + mInitMode = 1; // First we set the CCDB manager - ccdb->setURL(url.value); - ccdb->setTimestamp(timestamp.value); + ccdb->setURL(mUrl); + ccdb->setTimestamp(mTimestamp); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); // Not later than now objects ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); // Then the information about the metadata - if (passName.value == "metadata") { + if (mReconstructionPass == "metadata") { LOG(info) << "Getting pass from metadata"; if (metadataInfo.isMC()) { - passName.value = metadataInfo.get("AnchorPassName"); + mReconstructionPass = metadataInfo.get("AnchorPassName"); } else { - passName.value = metadataInfo.get("RecoPassName"); + mReconstructionPass = metadataInfo.get("RecoPassName"); } - LOG(info) << "Passed autodetect mode for pass. Taking '" << passName.value << "'"; + LOG(info) << "Passed autodetect mode for pass. Taking '" << mReconstructionPass << "'"; } - LOG(info) << "Using parameter collection, starting from pass '" << passName.value << "'"; + LOG(info) << "Using parameter collection, starting from pass '" << mReconstructionPass << "'"; - const std::string fname = paramFileName.value; + const std::string fname = mParamFileName; if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << parametrizationPath.value; + LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << mParametrizationPath; if (1) { o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, parametrizationPath.value); + paramCollection.loadParamFromFile(fname, mParametrizationPath); LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV3, passName.value)) { - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + if (!paramCollection.retrieveParameters(mRespParamsV3, mReconstructionPass)) { + if (mFatalOnPassNotAvailable) { + LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); } } else { - mRespParamsV3.setMomentumChargeShiftParameters(paramCollection.getPars(passName.value)); + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection.getPars(mReconstructionPass)); mRespParamsV3.printMomentumChargeShiftParameters(); } } else { - mRespParamsV3.loadParamFromFile(fname.data(), parametrizationPath.value); + mRespParamsV3.loadParamFromFile(fname.data(), mParametrizationPath); } - } else if (loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << parametrizationPath.value << " for timestamp " << timestamp.value; - o2::tof::ParameterCollection* paramCollection = ccdb->template getForTimeStamp(parametrizationPath.value, timestamp.value); + } else if (mLoadResponseFromCCDB) { // Loading it from CCDB + LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << mParametrizationPath << " for timestamp " << mTimestamp; + o2::tof::ParameterCollection* paramCollection = ccdb->template getForTimeStamp(mParametrizationPath, mTimestamp); paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV3, passName.value)) { // Attempt at loading the parameters with the pass defined - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + if (!paramCollection->retrieveParameters(mRespParamsV3, mReconstructionPass)) { // Attempt at loading the parameters with the pass defined + if (mFatalOnPassNotAvailable) { + LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); } } else { // Pass is available, load non standard parameters - mRespParamsV3.setMomentumChargeShiftParameters(paramCollection->getPars(passName.value)); + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection->getPars(mReconstructionPass)); mRespParamsV3.printMomentumChargeShiftParameters(); } } + // Calibration object is defined mRespParamsV3.print(); - if (timeShiftCCDBPath.value != "") { - if (timeShiftCCDBPath.value.find(".root") != std::string::npos) { - mRespParamsV3.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Pos", true); - mRespParamsV3.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Neg", false); + + // Loading additional calibration objects + if (mTimeShiftCCDBPathPos != "") { + if (mTimeShiftCCDBPathPos.find(".root") != std::string::npos) { + mRespParamsV3.setTimeShiftParameters(mTimeShiftCCDBPathPos, "ccdb_object", true); + } else { + if (mReconstructionPass == "") { + mRespParamsV3.setTimeShiftParameters(ccdb->template getForTimeStamp(mTimeShiftCCDBPathPos, mTimestamp), true); + } else { + std::map metadata; + metadata["RecoPassName"] = mReconstructionPass; + mRespParamsV3.setTimeShiftParameters(ccdb->template getSpecific(mTimeShiftCCDBPathPos, mTimestamp, metadata), true); + } + } + } + if (mTimeShiftCCDBPathNeg != "") { + if (mTimeShiftCCDBPathNeg.find(".root") != std::string::npos) { + mRespParamsV3.setTimeShiftParameters(mTimeShiftCCDBPathNeg, "ccdb_object", false); + } else { + if (mReconstructionPass == "") { + mRespParamsV3.setTimeShiftParameters(ccdb->template getForTimeStamp(mTimeShiftCCDBPathNeg, mTimestamp), false); + } else { + std::map metadata; + metadata["RecoPassName"] = mReconstructionPass; + mRespParamsV3.setTimeShiftParameters(ccdb->template getSpecific(mTimeShiftCCDBPathNeg, mTimestamp, metadata), false); + } + } + } + } + + template + void processSetup(o2::pid::tof::TOFResoParamsV3& mRespParamsV3, + CCDBObject ccdb, + const BcType& bc) + { + LOG(debug) << "Processing setup for run number " << bc.runNumber() << " from run " << mLastRunNumber; + // First we check if this run number was already processed + if (mLastRunNumber == bc.runNumber()) { + return; + } + mLastRunNumber = bc.runNumber(); + mTimestamp = bc.timestamp(); + + // Check the beam type + o2::parameters::GRPLHCIFData* grpo = ccdb->template getForTimeStamp(mPathGrpLhcIf, + mTimestamp); + if (mCollisionSystem == -1) { + mCollisionSystem = CollisionSystemType::getCollisionTypeFromGrp(grpo); + } else { + LOG(debug) << "Not setting collisions system as already set to " << mCollisionSystem << " " << CollisionSystemType::getCollisionSystemName(mCollisionSystem); + } + + if (!mEnableTimeDependentResponse) { + return; + } + LOG(debug) << "Updating parametrization from path '" << mParametrizationPath << "' and timestamp " << mTimestamp; + if (!ccdb->template getForTimeStamp(mParametrizationPath, mTimestamp)->retrieveParameters(mRespParamsV3, mReconstructionPass)) { + if (mFatalOnPassNotAvailable) { + LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); } else { - mRespParamsV3.setTimeShiftParameters(ccdb->template getForTimeStamp(Form("%s/pos", timeShiftCCDBPath.value.c_str()), timestamp.value), true); - mRespParamsV3.setTimeShiftParameters(ccdb->template getForTimeStamp(Form("%s/neg", timeShiftCCDBPath.value.c_str()), timestamp.value), false); + LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); } } + return; } + + bool autoSetProcessFunctions() const { return mAutoSetProcessFunctions; } + int collisionSystem() const { return mCollisionSystem; } + + private: + int mLastRunNumber = -1; // Last run number for which the calibration was loaded + int mInitMode = 0; // 0: no init, 1: init, 2: inherit + + // Configurable options + std::string mUrl; + std::string mPathGrpLhcIf; + int64_t mTimestamp; + std::string mTimeShiftCCDBPathPos; + std::string mTimeShiftCCDBPathNeg; + std::string mParamFileName; + std::string mParametrizationPath; + std::string mReconstructionPass; + bool mLoadResponseFromCCDB; + bool mFatalOnPassNotAvailable; + bool mEnableTimeDependentResponse; + int mCollisionSystem; + bool mAutoSetProcessFunctions; }; // Part 1 TOF signal definition /// Selection criteria for tracks used for TOF event time -float trackDistanceForGoodMatch = 999.f; -float trackDistanceForGoodMatchLowMult = 999.f; -int multiplicityThreshold = 0; -using Run3Trks = o2::soa::Join; -using Run3Cols = aod::Collisions; -bool isTrackGoodMatchForTOFPID(const Run3Trks::iterator& tr, const Run3Cols& /*ev*/) +bool isTrackGoodMatchForTOFPID(const Run3Trks::iterator& tr) { if (!tr.hasTOF()) { return false; @@ -179,16 +274,33 @@ struct tofSignal { // Running flags bool enableTableTOFSignal = false; // Flag to check if the TOF signal table is requested or not bool enableTablepidTOFFlags = false; // Flag to check if the TOF signal flags table is requested or not - TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration - Configurable distanceForGoodMatch{"distanceForGoodMatch", 999.f, "Maximum distance to consider a good match"}; - Configurable distanceForGoodMatchLowMult{"distanceForGoodMatchLowMult", 999.f, "Maximum distance to consider a good match for low multiplicity events"}; - Configurable multThreshold{"multThreshold", 0, "Multiplicity threshold to consider a low multiplicity event"}; // Output histograms Configurable enableQaHistograms{"enableQaHistograms", false, "Flag to enable the QA histograms"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + // Detector response and input parameters + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + Service ccdb; + struct : ConfigurableGroup { + Configurable cfgUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable cfgPathGrpLhcIf{"ccdb-path-grplhcif", "GLO/Config/GRPLHCIF", "Path on the CCDB for the GRPLHCIF object"}; + Configurable cfgTimestamp{"ccdb-timestamp", -1, "timestamp of the object"}; + Configurable cfgTimeShiftCCDBPathPos{"timeShiftCCDBPathPos", "", "Path of the TOF time shift vs eta for pos. tracks. If empty none is taken"}; + Configurable cfgTimeShiftCCDBPathNeg{"timeShiftCCDBPathNeg", "", "Path of the TOF time shift vs eta for neg. tracks. If empty none is taken"}; + Configurable cfgParamFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; + Configurable cfgParametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; + Configurable cfgReconstructionPass{"reconstructionPass", "", {"Apass to use when fetching the calibration tables. Empty (default) does not check for any pass. Use `metadata` to fetch it from the AO2D metadata. Otherwise it will override the metadata."}}; + Configurable cfgLoadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; + Configurable cfgFatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; + Configurable cfgEnableTimeDependentResponse{"enableTimeDependentResponse", false, "Flag to use the collision timestamp to fetch the PID Response"}; + Configurable cfgCollisionSystem{"collisionSystem", -1, "Collision system: -1 (autoset), 0 (pp), 1 (PbPb), 2 (XeXe), 3 (pPb)"}; + Configurable cfgAutoSetProcessFunctions{"autoSetProcessFunctions", true, "Flag to autodetect the process functions to use"}; + } cfg; // Configurables (only defined here and inherited from other tasks) + + TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration void init(o2::framework::InitContext& initContext) { + mTOFCalibConfig.init(cfg); // Checking that the table is requested in the workflow and enabling it enableTableTOFSignal = isTableRequiredInWorkflow(initContext, "TOFSignal"); if (enableTableTOFSignal) { @@ -204,11 +316,14 @@ struct tofSignal { LOG(info) << "No table or process is enabled. Disabling task"; return; } - if (metadataInfo.isFullyDefined() && !doprocessRun2 && !doprocessRun3) { // Check if the metadata is initialized (only if not forced from the workflow configuration) - if (metadataInfo.isRun3()) { - doprocessRun3.value = true; - } else { - doprocessRun2.value = false; + if (mTOFCalibConfig.autoSetProcessFunctions()) { + LOG(info) << "Autodetecting process functions"; + if (metadataInfo.isFullyDefined() && !doprocessRun2 && !doprocessRun3) { // Check if the metadata is initialized (only if not forced from the workflow configuration) + if (metadataInfo.isRun3()) { + doprocessRun3.value = true; + } else { + doprocessRun2.value = false; + } } } @@ -219,11 +334,7 @@ struct tofSignal { if (!doprocessRun2 && !doprocessRun3) { LOG(fatal) << "Neither processRun2 nor processRun3 are enabled. Pick one of the two"; } - - trackDistanceForGoodMatch = distanceForGoodMatch; - trackDistanceForGoodMatchLowMult = distanceForGoodMatchLowMult; - multiplicityThreshold = multThreshold; - LOG(info) << "Configuring selections for good match: " << trackDistanceForGoodMatch << " low mult " << trackDistanceForGoodMatchLowMult << " mult. threshold " << multiplicityThreshold; + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); // Getting the parametrization parameters if (!enableQaHistograms) { return; } @@ -236,7 +347,7 @@ struct tofSignal { /// Dummy process function for BCs, needed in case both Run2 and Run3 process functions are disabled void process(aod::BCs const&) {} - void processRun3(Run3Trks const& tracks, Run3Cols const& collisions) + void processRun3(Run3Trks const& tracks) { if (!enableTableTOFSignal) { return; @@ -245,26 +356,25 @@ struct tofSignal { if (enableTablepidTOFFlags) { tableFlags.reserve(tracks.size()); } - for (auto& t : tracks) { - const auto s = o2::pid::tof::TOFSignal::GetTOFSignal(t); + for (auto& trk : tracks) { + const float& sig = o2::pid::tof::TOFSignal::GetTOFSignal(trk); if (enableQaHistograms) { - histos.fill(HIST("tofSignal"), s); + histos.fill(HIST("tofSignal"), sig); } - table(s); + table(sig); if (!enableTablepidTOFFlags) { continue; } - const auto b = isTrackGoodMatchForTOFPID(t, collisions); + const auto& b = isTrackGoodMatchForTOFPID(trk); if (enableQaHistograms) { - histos.fill(HIST("goodForPIDFlags"), s); + histos.fill(HIST("goodForPIDFlags"), sig); } tableFlags(b); } } PROCESS_SWITCH(tofSignal, processRun3, "Process Run3 data i.e. input is TrackIU. Set to false to autodetect from metadata.", false); - using TrksRun2 = o2::soa::Join; - void processRun2(TrksRun2 const& tracks) + void processRun2(Run2Trks const& tracks) { if (!enableTableTOFSignal) { return; @@ -273,8 +383,8 @@ struct tofSignal { if (enableTablepidTOFFlags) { tableFlags.reserve(tracks.size()); } - for (auto& t : tracks) { - table(o2::pid::tof::TOFSignal::GetTOFSignal(t)); + for (auto& trk : tracks) { + table(o2::pid::tof::TOFSignal::GetTOFSignal(trk)); if (!enableTablepidTOFFlags) { continue; } @@ -290,7 +400,11 @@ float trackSampleMaxMomentum = 2.f; template bool filterForTOFEventTime(const trackType& tr) { - return (tr.hasTOF() && tr.p() > trackSampleMinMomentum && tr.p() < trackSampleMaxMomentum && tr.hasITS() && tr.hasTPC() && (tr.trackType() == o2::aod::track::TrackTypeEnum::Track || tr.trackType() == o2::aod::track::TrackTypeEnum::TrackIU)); + return (tr.hasTOF() && + tr.p() > trackSampleMinMomentum && tr.p() < trackSampleMaxMomentum && + tr.hasITS() && + tr.hasTPC() && + (tr.trackType() == o2::aod::track::TrackTypeEnum::Track || tr.trackType() == o2::aod::track::TrackTypeEnum::TrackIU)); } // accept all /// Specialization of TOF event time maker @@ -331,10 +445,13 @@ struct tofEventTime { Configurable maxMomentum{"maxMomentum", 2.0f, "Maximum momentum to select track sample for TOF event time"}; Configurable maxEvTimeTOF{"maxEvTimeTOF", 100000.0f, "Maximum value of the TOF event time"}; Configurable sel8TOFEvTime{"sel8TOFEvTime", false, "Flag to compute the ev. time only for events that pass the sel8 ev. selection"}; + Configurable mComputeEvTimeWithTOF{"computeEvTimeWithTOF", -1, "Compute ev. time with TOF. -1 (autoset), 0 no, 1 yes"}; + Configurable mComputeEvTimeWithFT0{"computeEvTimeWithFT0", -1, "Compute ev. time with FT0. -1 (autoset), 0 no, 1 yes"}; Configurable maxNtracksInSet{"maxNtracksInSet", 10, "Size of the set to consider for the TOF ev. time computation"}; void init(o2::framework::InitContext& initContext) { + mTOFCalibConfig.inheritFromBaseTask(initContext); // Checking that the table is requested in the workflow and enabling it enableTableTOFEvTime = isTableRequiredInWorkflow(initContext, "TOFEvTime"); @@ -353,8 +470,24 @@ struct tofEventTime { return; } - if (metadataInfo.isFullyDefined() && metadataInfo.isRun3() && doprocessRun2) { - LOG(fatal) << "Run2 process function is enabled but the metadata says it is Run3"; + if (mTOFCalibConfig.autoSetProcessFunctions()) { + LOG(info) << "Autodetecting process functions"; + if (metadataInfo.isFullyDefined()) { + if (metadataInfo.isRun3()) { + doprocessRun3.value = true; + } else { + doprocessRun2.value = true; + } + } + } + + if (metadataInfo.isFullyDefined()) { + if (metadataInfo.isRun3() && doprocessRun2) { + LOG(fatal) << "Run2 process function is enabled but the metadata says it is Run3"; + } + if (!metadataInfo.isRun3() && doprocessRun3) { + LOG(fatal) << "Run3 process function is enabled but the metadata says it is Run2"; + } } trackSampleMinMomentum = minMomentum; @@ -366,16 +499,8 @@ struct tofEventTime { LOGF(info, "Enabling process function: processRun2"); nEnabled++; } - if (doprocessNoFT0 == true) { - LOGF(info, "Enabling process function: processNoFT0"); - nEnabled++; - } - if (doprocessFT0 == true) { - LOGF(info, "Enabling process function: processFT0"); - nEnabled++; - } - if (doprocessOnlyFT0 == true) { - LOGF(info, "Enabling process function: processOnlyFT0"); + if (doprocessRun3 == true) { + LOGF(info, "Enabling process function: processRun3"); nEnabled++; } if (nEnabled > 1) { @@ -385,7 +510,7 @@ struct tofEventTime { if (sel8TOFEvTime.value == true) { LOG(info) << "TOF event time will be computed for collisions that pass the event selection only!"; } - mTOFCalibConfig.setUp(mRespParamsV3, ccdb); // Getting the parametrization parameters + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); // Getting the parametrization parameters o2::tof::eventTimeContainer::setMaxNtracksInSet(maxNtracksInSet.value); o2::tof::eventTimeContainer::printConfig(); @@ -415,210 +540,213 @@ struct tofEventTime { tableEvTime(t.collision().collisionTime() * 1000.f, t.collision().collisionTimeRes() * 1000.f); } } - PROCESS_SWITCH(tofEventTime, processRun2, "Process with Run2 data", false); + PROCESS_SWITCH(tofEventTime, processRun2, "Process with Run2 data", true); /// /// Process function to prepare the event for each track on Run 3 data without the FT0 - using TrksEvTime = soa::Join; // Define slice per collision - Preslice perCollision = aod::track::collisionId; + Preslice perCollision = aod::track::collisionId; template - using ResponseImplementationEvTime = o2::pid::tof::ExpTimes; - using EvTimeCollisions = soa::Join; - void processNoFT0(TrksEvTime const& tracks, - EvTimeCollisions const&) + using ResponseImplementationEvTime = o2::pid::tof::ExpTimes; + void processRun3(Run3TrksWtof& tracks, + aod::FT0s const&, + EvTimeCollisionsFT0 const&, + aod::BCsWithTimestamps const&) { if (!enableTableTOFEvTime) { return; } + LOG(debug) << "Processing Run3 data for TOF event time"; tableEvTime.reserve(tracks.size()); tableFlags.reserve(tracks.size()); if (enableTableEvTimeTOFOnly) { tableEvTimeTOFOnly.reserve(tracks.size()); } - - int lastCollisionId = -1; // Last collision ID analysed - for (auto const& t : tracks) { // Loop on collisions - if (!t.has_collision() || ((sel8TOFEvTime.value == true) && !t.collision_as().sel8())) { // Track was not assigned, cannot compute event time or event did not pass the event selection - tableFlags(0); - tableEvTime(0.f, 999.f); - if (enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly((uint8_t)0, 0.f, 0.f, -1); - } + bool calibUpdated = false; + for (auto const& track : tracks) { // Loop on all tracks + if (!track.has_collision()) { // Skipping tracks without collisions continue; } - if (t.collisionId() == lastCollisionId) { // Event time from this collision is already in the table + const auto& coll = track.collision_as(); + if (!coll.has_bc()) { continue; } - /// Create new table for the tracks in a collision - lastCollisionId = t.collisionId(); /// Cache last collision ID - - const auto& tracksInCollision = tracks.sliceBy(perCollision, lastCollisionId); - - // First make table for event time - const auto evTimeTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV3, diamond); - int nGoodTracksForTOF = 0; - float et = evTimeTOF.mEventTime; - float erret = evTimeTOF.mEventTimeError; + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, coll.bc_as()); // Update the calibration parameters + calibUpdated = true; + break; + } - for (auto const& trk : tracksInCollision) { // Loop on Tracks - if constexpr (removeTOFEvTimeBias) { - evTimeTOF.removeBias(trk, nGoodTracksForTOF, et, erret, 2); - } - uint8_t flags = 0; - if (erret < errDiamond && (maxEvTimeTOF <= 0.f || abs(et) < maxEvTimeTOF)) { - flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeTOF; - } else { - et = 0.f; - erret = errDiamond; - } - tableFlags(flags); - tableEvTime(et, erret); - if (enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly((uint8_t)filterForTOFEventTime(trk), et, erret, evTimeTOF.mEventTimeMultiplicity); + // Autoset the processing mode for the event time computation + if (calibUpdated) { + if (mComputeEvTimeWithTOF == -1 || mComputeEvTimeWithFT0 == -1) { + switch (mTOFCalibConfig.collisionSystem()) { + case CollisionSystemType::kCollSyspp: // pp + mComputeEvTimeWithTOF.value = ((mComputeEvTimeWithTOF == -1) ? 0 : mComputeEvTimeWithTOF.value); + mComputeEvTimeWithFT0.value = ((mComputeEvTimeWithFT0 == -1) ? 1 : mComputeEvTimeWithFT0.value); + break; + case CollisionSystemType::kCollSysPbPb: // PbPb + mComputeEvTimeWithTOF.value = ((mComputeEvTimeWithTOF == -1) ? 1 : mComputeEvTimeWithTOF.value); + mComputeEvTimeWithFT0.value = ((mComputeEvTimeWithFT0 == -1) ? 0 : mComputeEvTimeWithFT0.value); + break; + default: + LOG(fatal) << "Collision system " << mTOFCalibConfig.collisionSystem() << " " << CollisionSystemType::getCollisionSystemName(mTOFCalibConfig.collisionSystem()) << " not supported for TOF event time computation"; + break; } } + } else { + LOG(warning) << "Calibration not updated on " << tracks.size() << " tracks !!"; } - } - PROCESS_SWITCH(tofEventTime, processNoFT0, "Process without FT0", false); - - /// - /// Process function to prepare the event for each track on Run 3 data with the FT0 - using EvTimeCollisionsFT0 = soa::Join; - void processFT0(TrksEvTime& tracks, - aod::FT0s const&, - EvTimeCollisionsFT0 const&) - { - if (!enableTableTOFEvTime) { - return; - } + LOG(debug) << "Running on " << CollisionSystemType::getCollisionSystemName(mTOFCalibConfig.collisionSystem()) << " mComputeEvTimeWithTOF " << mComputeEvTimeWithTOF.value << " mComputeEvTimeWithFT0 " << mComputeEvTimeWithFT0.value; - tableEvTime.reserve(tracks.size()); - tableFlags.reserve(tracks.size()); - if (enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly.reserve(tracks.size()); - } - - int lastCollisionId = -1; // Last collision ID analysed - for (auto const& t : tracks) { // Loop on collisions - if (!t.has_collision() || ((sel8TOFEvTime.value == true) && !t.collision_as().sel8())) { // Track was not assigned, cannot compute event time or event did not pass the event selection - tableFlags(0); - tableEvTime(0.f, 999.f); - if (enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly((uint8_t)0, 0.f, 0.f, -1); + if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 1) { + int lastCollisionId = -1; // Last collision ID analysed + for (auto const& t : tracks) { // Loop on collisions + if (!t.has_collision() || ((sel8TOFEvTime.value == true) && !t.collision_as().sel8())) { // Track was not assigned, cannot compute event time or event did not pass the event selection + tableFlags(0); + tableEvTime(0.f, 999.f); + if (enableTableEvTimeTOFOnly) { + tableEvTimeTOFOnly((uint8_t)0, 0.f, 0.f, -1); + } + continue; } - continue; - } - if (t.collisionId() == lastCollisionId) { // Event time from this collision is already in the table - continue; - } - /// Create new table for the tracks in a collision - lastCollisionId = t.collisionId(); /// Cache last collision ID - - const auto& tracksInCollision = tracks.sliceBy(perCollision, lastCollisionId); - const auto& collision = t.collision_as(); - - // Compute the TOF event time - const auto evTimeTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV3, diamond); - - float t0AC[2] = {.0f, 999.f}; // Value and error of T0A or T0C or T0AC - float t0TOF[2] = {static_cast(evTimeTOF.mEventTime), static_cast(evTimeTOF.mEventTimeError)}; // Value and error of TOF - - uint8_t flags = 0; - int nGoodTracksForTOF = 0; - float eventTime = 0.f; - float sumOfWeights = 0.f; - float weight = 0.f; - - for (auto const& trk : tracksInCollision) { // Loop on Tracks - // Reset the flag - flags = 0; - // Reset the event time - eventTime = 0.f; - sumOfWeights = 0.f; - weight = 0.f; - // Remove the bias on TOF ev. time - if constexpr (removeTOFEvTimeBias) { - evTimeTOF.removeBias(trk, nGoodTracksForTOF, t0TOF[0], t0TOF[1], 2); + if (t.collisionId() == lastCollisionId) { // Event time from this collision is already in the table + continue; } - if (t0TOF[1] < errDiamond && (maxEvTimeTOF <= 0 || abs(t0TOF[0]) < maxEvTimeTOF)) { - flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeTOF; + /// Create new table for the tracks in a collision + lastCollisionId = t.collisionId(); /// Cache last collision ID - weight = 1.f / (t0TOF[1] * t0TOF[1]); - eventTime += t0TOF[0] * weight; - sumOfWeights += weight; - } + const auto& tracksInCollision = tracks.sliceBy(perCollision, lastCollisionId); + const auto& collision = t.collision_as(); - if (collision.has_foundFT0()) { // T0 measurement is available - // const auto& ft0 = collision.foundFT0(); - if (collision.t0ACValid()) { - t0AC[0] = collision.t0AC() * 1000.f; - t0AC[1] = collision.t0resolution() * 1000.f; - flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC; + // Compute the TOF event time + const auto evTimeMakerTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV3, diamond); + + float t0AC[2] = {.0f, 999.f}; // Value and error of T0A or T0C or T0AC + float t0TOF[2] = {static_cast(evTimeMakerTOF.mEventTime), static_cast(evTimeMakerTOF.mEventTimeError)}; // Value and error of TOF + + uint8_t flags = 0; + int nGoodTracksForTOF = 0; + float eventTime = 0.f; + float sumOfWeights = 0.f; + float weight = 0.f; + + for (auto const& trk : tracksInCollision) { // Loop on Tracks + // Reset the flag + flags = 0; + // Reset the event time + eventTime = 0.f; + sumOfWeights = 0.f; + weight = 0.f; + // Remove the bias on TOF ev. time + if constexpr (removeTOFEvTimeBias) { + evTimeMakerTOF.removeBias(trk, nGoodTracksForTOF, t0TOF[0], t0TOF[1], 2); } + if (t0TOF[1] < errDiamond && (maxEvTimeTOF <= 0 || abs(t0TOF[0]) < maxEvTimeTOF)) { + flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeTOF; - weight = 1.f / (t0AC[1] * t0AC[1]); - eventTime += t0AC[0] * weight; - sumOfWeights += weight; - } + weight = 1.f / (t0TOF[1] * t0TOF[1]); + eventTime += t0TOF[0] * weight; + sumOfWeights += weight; + } + + if (collision.has_foundFT0()) { // T0 measurement is available + // const auto& ft0 = collision.foundFT0(); + if (collision.t0ACValid()) { + t0AC[0] = collision.t0AC() * 1000.f; + t0AC[1] = collision.t0resolution() * 1000.f; + flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC; + } + + weight = 1.f / (t0AC[1] * t0AC[1]); + eventTime += t0AC[0] * weight; + sumOfWeights += weight; + } - if (sumOfWeights < weightDiamond) { // avoiding sumOfWeights = 0 or worse that diamond - eventTime = 0; - sumOfWeights = weightDiamond; + if (sumOfWeights < weightDiamond) { // avoiding sumOfWeights = 0 or worse that diamond + eventTime = 0; + sumOfWeights = weightDiamond; + tableFlags(0); + } else { + tableFlags(flags); + } + tableEvTime(eventTime / sumOfWeights, sqrt(1. / sumOfWeights)); + if (enableTableEvTimeTOFOnly) { + tableEvTimeTOFOnly((uint8_t)filterForTOFEventTime(trk), t0TOF[0], t0TOF[1], evTimeMakerTOF.mEventTimeMultiplicity); + } + } + } + } else if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 0) { + int lastCollisionId = -1; // Last collision ID analysed + for (auto const& t : tracks) { // Loop on collisions + if (!t.has_collision() || ((sel8TOFEvTime.value == true) && !t.collision_as().sel8())) { // Track was not assigned, cannot compute event time or event did not pass the event selection tableFlags(0); - } else { - tableFlags(flags); + tableEvTime(0.f, 999.f); + if (enableTableEvTimeTOFOnly) { + tableEvTimeTOFOnly((uint8_t)0, 0.f, 0.f, -1); + } + continue; } - tableEvTime(eventTime / sumOfWeights, sqrt(1. / sumOfWeights)); - if (enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly((uint8_t)filterForTOFEventTime(trk), t0TOF[0], t0TOF[1], evTimeTOF.mEventTimeMultiplicity); + if (t.collisionId() == lastCollisionId) { // Event time from this collision is already in the table + continue; } - } - } - } - PROCESS_SWITCH(tofEventTime, processFT0, "Process with FT0", false); + /// Create new table for the tracks in a collision + lastCollisionId = t.collisionId(); /// Cache last collision ID - /// - /// Process function to prepare the event for each track on Run 3 data with only the FT0 - void processOnlyFT0(TrksEvTime& tracks, - aod::FT0s const&, - EvTimeCollisionsFT0 const&) - { - if (!enableTableTOFEvTime) { - return; - } + const auto& tracksInCollision = tracks.sliceBy(perCollision, lastCollisionId); - tableEvTime.reserve(tracks.size()); - tableFlags.reserve(tracks.size()); - if (!enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly.reserve(tracks.size()); - } + // First make table for event time + const auto evTimeMakerTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV3, diamond); + int nGoodTracksForTOF = 0; + float et = evTimeMakerTOF.mEventTime; + float erret = evTimeMakerTOF.mEventTimeError; - for (auto const& t : tracks) { // Loop on collisions - if (enableTableEvTimeTOFOnly) { - tableEvTimeTOFOnly((uint8_t)0, 0.f, 0.f, -1); - } - if (!t.has_collision()) { // Track was not assigned, cannot compute event time - tableFlags(0); - tableEvTime(0.f, 999.f); - continue; + for (auto const& trk : tracksInCollision) { // Loop on Tracks + if constexpr (removeTOFEvTimeBias) { + evTimeMakerTOF.removeBias(trk, nGoodTracksForTOF, et, erret, 2); + } + uint8_t flags = 0; + if (erret < errDiamond && (maxEvTimeTOF <= 0.f || abs(et) < maxEvTimeTOF)) { + flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeTOF; + } else { + et = 0.f; + erret = errDiamond; + } + tableFlags(flags); + tableEvTime(et, erret); + if (enableTableEvTimeTOFOnly) { + tableEvTimeTOFOnly((uint8_t)filterForTOFEventTime(trk), et, erret, evTimeMakerTOF.mEventTimeMultiplicity); + } + } } - const auto& collision = t.collision_as(); - - if (collision.has_foundFT0()) { // T0 measurement is available - // const auto& ft0 = collision.foundFT0(); - if (collision.t0ACValid()) { - tableFlags(o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC); - tableEvTime(collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f); + } else if (mComputeEvTimeWithTOF == 0 && mComputeEvTimeWithFT0 == 1) { + for (auto const& t : tracks) { // Loop on collisions + if (enableTableEvTimeTOFOnly) { + tableEvTimeTOFOnly((uint8_t)0, 0.f, 0.f, -1); + } + if (!t.has_collision()) { // Track was not assigned, cannot compute event time + tableFlags(0); + tableEvTime(0.f, 999.f); continue; } + const auto& collision = t.collision_as(); + + if (collision.has_foundFT0()) { // T0 measurement is available + // const auto& ft0 = collision.foundFT0(); + if (collision.t0ACValid()) { + tableFlags(o2::aod::pidflags::enums::PIDFlags::EvTimeT0AC); + tableEvTime(collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f); + continue; + } + } + tableFlags(0); + tableEvTime(0.f, 999.f); } - tableFlags(0); - tableEvTime(0.f, 999.f); + } else { + LOG(fatal) << "Invalid configuration for TOF event time computation"; } } - PROCESS_SWITCH(tofEventTime, processOnlyFT0, "Process only with FT0", false); + PROCESS_SWITCH(tofEventTime, processRun3, "Process the Run3 data", true); }; // Part 3 Nsigma computation @@ -673,9 +801,7 @@ struct tofPidMerge { o2::pid::tof::TOFResoParamsV3 mRespParamsV3; Service ccdb; TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration - // Configurable inheritFromBaseTask{"inheritFromBaseTask", true, "Flag to iherit all common configurables from the TOF base task"}; Configurable enableQaHistograms{"enableQaHistograms", false, "Flag to enable the QA histograms"}; - Configurable enableTimeDependentResponse{"enableTimeDependentResponse", false, "Flag to use the collision timestamp to fetch the PID Response"}; // Configuration flags to include and exclude particle hypotheses Configurable> enableParticle{"enableParticle", @@ -693,6 +819,7 @@ struct tofPidMerge { std::vector mEnabledParticlesFull; // Vector of enabled PID hypotheses to loop on when making full tables void init(o2::framework::InitContext& initContext) { + mTOFCalibConfig.inheritFromBaseTask(initContext); // Checking the tables are requested in the workflow and enabling them for (int i = 0; i < nSpecies; i++) { // First checking tiny @@ -716,7 +843,7 @@ struct tofPidMerge { } else if (doprocessData.value == false) { LOG(fatal) << "PID tables are required but process data is disabled. Please enable it"; } - mTOFCalibConfig.setUp(mRespParamsV3, ccdb); // Getting the parametrization parameters + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); // Getting the parametrization parameters // Printing enabled tables and enabling QA histograms if needed LOG(info) << "++ Enabled tables:"; @@ -904,10 +1031,11 @@ struct tofPidMerge { void process(aod::BCs const&) {} - using Trks = soa::Join; template - using ResponseImplementation = o2::pid::tof::ExpTimes; - void processData(Trks const& tracks, aod::Collisions const&, aod::BCsWithTimestamps const&) + using ResponseImplementation = o2::pid::tof::ExpTimes; + void processData(Run3TrksWtofWevTime const& tracks, + Run3Cols const&, + aod::BCsWithTimestamps const&) { constexpr auto responseEl = ResponseImplementation(); constexpr auto responseMu = ResponseImplementation(); @@ -923,17 +1051,11 @@ struct tofPidMerge { if (!track.has_collision()) { // Skipping tracks without collisions continue; } - mTOFCalibConfig.timestamp.value = track.collision().bc_as().timestamp(); - if (enableTimeDependentResponse) { - LOG(debug) << "Updating parametrization from path '" << mTOFCalibConfig.parametrizationPath.value << "' and timestamp " << mTOFCalibConfig.timestamp.value; - if (!ccdb->getForTimeStamp(mTOFCalibConfig.parametrizationPath.value, mTOFCalibConfig.timestamp.value)->retrieveParameters(mRespParamsV3, mTOFCalibConfig.passName.value)) { - if (mTOFCalibConfig.fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", mTOFCalibConfig.passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", mTOFCalibConfig.passName.value.data()); - } - } + const auto& coll = track.collision(); + if (!coll.has_bc()) { + continue; } + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, coll.bc_as()); // Update the calibration parameters break; } @@ -1098,17 +1220,22 @@ struct tofPidBeta { bool enableTableMass = false; void init(o2::framework::InitContext& initContext) { + mTOFCalibConfig.inheritFromBaseTask(initContext); enableTableBeta = isTableRequiredInWorkflow(initContext, "pidTOFbeta"); enableTableMass = isTableRequiredInWorkflow(initContext, "pidTOFmass"); if (!enableTableBeta && !enableTableMass && !doprocessRun2 && !doprocessRun3) { LOG(info) << "No table or process is enabled. Disabling task"; return; } - if (metadataInfo.isFullyDefined()) { - if (metadataInfo.isRun3()) { - doprocessRun3.value = true; - } else { - doprocessRun2.value = true; + + if (mTOFCalibConfig.autoSetProcessFunctions()) { + LOG(info) << "Autodetecting process functions"; + if (metadataInfo.isFullyDefined()) { + if (metadataInfo.isRun3()) { + doprocessRun3.value = true; + } else { + doprocessRun2.value = true; + } } } @@ -1116,14 +1243,13 @@ struct tofPidBeta { if (!enableTOFParams) { return; } - mTOFCalibConfig.setUp(mRespParamsV3, ccdb); // Getting the parametrization parameters + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); // Getting the parametrization parameters } void process(aod::BCs const&) {} - using TrksRun2 = soa::Join; - o2::pid::tof::Beta responseBetaRun2; - void processRun2(TrksRun2 const& tracks) + o2::pid::tof::Beta responseBetaRun2; + void processRun2(Run2TrksWtofWevTime const& tracks) { if (!enableTableBeta && !enableTableMass) { return; @@ -1137,18 +1263,17 @@ struct tofPidBeta { } if (enableTableMass) { if (enableTOFParams) { - tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk.tofExpMom() / (1.f + trk.sign() * mRespParamsV3.getMomentumChargeShift(trk.eta())), beta)); + tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk.tofExpMom() / (1.f + trk.sign() * mRespParamsV3.getMomentumChargeShift(trk.eta())), beta)); } else { - tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk, beta)); + tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk, beta)); } } } } - PROCESS_SWITCH(tofPidBeta, processRun2, "Process Run3 data i.e. input is TrackIU. If false, taken from metadata automatically", false); + PROCESS_SWITCH(tofPidBeta, processRun2, "Process Run3 data i.e. input is TrackIU. If false, taken from metadata automatically", true); - using Trks = soa::Join; - o2::pid::tof::Beta responseBeta; - void processRun3(Trks const& tracks) + o2::pid::tof::Beta responseBeta; + void processRun3(Run3TrksWtofWevTime const& tracks) { if (!enableTableBeta && !enableTableMass) { return; @@ -1163,14 +1288,14 @@ struct tofPidBeta { } if (enableTableMass) { if (enableTOFParams) { - tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk.tofExpMom() / (1.f + trk.sign() * mRespParamsV3.getMomentumChargeShift(trk.eta())), beta)); + tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk.tofExpMom() / (1.f + trk.sign() * mRespParamsV3.getMomentumChargeShift(trk.eta())), beta)); } else { - tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk, beta)); + tablePIDTOFMass(o2::pid::tof::TOFMass::GetTOFMass(trk, beta)); } } } } - PROCESS_SWITCH(tofPidBeta, processRun3, "Process Run3 data i.e. input is TrackIU. If false, taken from metadata automatically", false); + PROCESS_SWITCH(tofPidBeta, processRun3, "Process Run3 data i.e. input is TrackIU. If false, taken from metadata automatically", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index f838b9f68cc..0801ee29a39 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -48,6 +48,7 @@ struct BcSelectionTask { Configurable confITSROFrameEndBorderMargin{"ITSROFrameEndBorderMargin", -1, "Number of bcs at the end of ITS RO Frame border. Take from CCDB if -1"}; Configurable confTimeFrameStartBorderMargin{"TimeFrameStartBorderMargin", -1, "Number of bcs to cut at the start of the Time Frame. Take from CCDB if -1"}; Configurable confTimeFrameEndBorderMargin{"TimeFrameEndBorderMargin", -1, "Number of bcs to cut at the end of the Time Frame. Take from CCDB if -1"}; + Configurable confCheckRunDurationLimits{"checkRunDurationLimits", false, "Check if the BCs are within the run duration limits"}; int lastRunNumber = -1; int64_t bcSOR = -1; // global bc of the start of the first orbit @@ -81,6 +82,7 @@ struct BcSelectionTask { histos.add("hCounterTCEafterBCcuts", "", kTH1D, {{1, 0., 1.}}); histos.add("hCounterZEMafterBCcuts", "", kTH1D, {{1, 0., 1.}}); histos.add("hCounterZNCafterBCcuts", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterInvalidBCTimestamp", "", kTH1D, {{1, 0., 1.}}); histos.add("hLumiTVX", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); histos.add("hLumiTCE", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); histos.add("hLumiZEM", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); @@ -228,10 +230,14 @@ struct BcSelectionTask { bcsel.reserve(bcs.size()); // extract ITS time frame parameters - - int64_t ts = bcs.iteratorAt(0).timestamp(); + int run = bcs.iteratorAt(0).runNumber(); + auto timestamps = ccdb->getRunDuration(run, true); /// fatalise if timestamps are not found + int64_t sorTimestamp = timestamps.first; // timestamp of the SOR/SOX/STF in ms + int64_t eorTimestamp = timestamps.second; // timestamp of the EOR/EOX/ETF in ms + int64_t ts = eorTimestamp / 2 + sorTimestamp / 2; // timestamp of the middle of the run auto alppar = ccdb->getForTimeStamp>("ITS/Config/AlpideParam", ts); - + EventSelectionParams* par = ccdb->getForTimeStamp("EventSelection/EventSelectionParams", ts); + TriggerAliases* aliases = ccdb->getForTimeStamp("EventSelection/TriggerAliases", ts); // map from GlobalBC to BcId needed to find triggerBc std::map mapGlobalBCtoBcId; for (auto& bc : bcs) { @@ -239,12 +245,10 @@ struct BcSelectionTask { } int triggerBcShift = confTriggerBcShift; if (confTriggerBcShift == 999) { - int run = bcs.iteratorAt(0).runNumber(); triggerBcShift = (run <= 526766 || (run >= 526886 && run <= 527237) || (run >= 527259 && run <= 527518) || run == 527523 || run == 527734 || run >= 534091) ? 0 : 294; } // extract run number and related information - int run = bcs.iteratorAt(0).runNumber(); if (run != lastRunNumber) { lastRunNumber = run; // do it only once if (run >= 500000) { // access CCDB for data or anchored MC only @@ -278,8 +282,6 @@ struct BcSelectionTask { // bc loop for (auto bc : bcs) { - EventSelectionParams* par = ccdb->getForTimeStamp("EventSelection/EventSelectionParams", bc.timestamp()); - TriggerAliases* aliases = ccdb->getForTimeStamp("EventSelection/TriggerAliases", bc.timestamp()); uint32_t alias{0}; // workaround for pp2022 (trigger info is shifted by -294 bcs) int32_t triggerBcId = mapGlobalBCtoBcId[bc.globalBC() + triggerBcShift]; @@ -422,6 +424,15 @@ struct BcSelectionTask { } } + if (bc.timestamp() < static_cast(sorTimestamp) || bc.timestamp() > static_cast(eorTimestamp)) { + histos.get(HIST("hCounterInvalidBCTimestamp"))->Fill(srun, 1); + if (confCheckRunDurationLimits.value) { + LOGF(warn, "Invalid BC timestamp: %d, run: %d, sor: %d, eor: %d", bc.timestamp(), run, sorTimestamp, eorTimestamp); + alias = 0u; + selection = 0u; + } + } + // Fill bc selection columns bcsel(alias, selection, foundFT0, foundFV0, foundFDD, foundZDC); } diff --git a/Common/TableProducer/match-mft-ft0.cxx b/Common/TableProducer/match-mft-ft0.cxx new file mode 100644 index 00000000000..268548255cd --- /dev/null +++ b/Common/TableProducer/match-mft-ft0.cxx @@ -0,0 +1,554 @@ +// 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 match-mft-ft0.cxx +// \author Sarah Herrmann +// +// \brief This code loops over every MFT tracks (except orphan tracks) and propagates +// them to the FT0-C, matching the signals in some BC to reduce track ambiguity +// It produces a table containing for each MFT track a list of BCs with an FT0C match +// called aod::BCofMFT +// \date 03/09/24 + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" + +#include "MathUtils/Utils.h" +#include "CommonConstants/LHCConstants.h" +#include "Common/Core/trackUtilities.h" //for getTrackPar() +#include "ReconstructionDataFormats/TrackFwd.h" //for propagate +// https://github.com/AliceO2Group/AliceO2/blob/dev/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackFwd.h +#include "CommonConstants/LHCConstants.h" +#include "Math/MatrixFunctions.h" +#include "Math/SMatrix.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" + +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "Field/MagneticField.h" +#include "TGeoGlobalMagField.h" + +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" + +#include "Common/DataModel/MatchMFTFT0.h" + +using SMatrix55 = ROOT::Math::SMatrix>; +using SMatrix5 = ROOT::Math::SVector; + +using namespace o2; +using namespace o2::framework; + +// Creating a table BC to FT0 and filling it +struct bctoft0c { + Produces mf; + struct { + std::vector ft0ids; + } filler; + void process(aod::BCs::iterator const& bc, soa::SmallGroups const& ft0s) + { + filler.ft0ids.clear(); + for (auto const& ft0 : ft0s) { + filler.ft0ids.emplace_back(ft0.globalIndex()); + } + mf(bc.globalIndex(), filler.ft0ids); + } +}; + +using ExtBCs = soa::Join; + +template +T getCompatibleBCs(aod::AmbiguousMFTTrack const& atrack, aod::Collision const& collOrig, T const& bcs, int deltaBC) +{ + // this method is unused for now, MFTtracks with no collisions (orphan tracks) are not considered for the matching with FT0C + auto compBCs = atrack.bc_as(); // BC + info on FT0 + auto bcIter = compBCs.begin(); // first element of compBC + uint64_t firstBC = bcIter.globalBC(); + + bcIter.moveToEnd(); // does it move to the end or the next one after the end ? + --bcIter; // to avoid a seg fault + uint64_t lastBC = bcIter.globalBC(); // gives the last COMPATIBLE BC in compBCs + + auto bcIt = collOrig.bc_as(); + + int64_t minBCId = bcIt.globalIndex(); + auto minGlobalBC = bcIt.globalBC(); + + if (bcIt.globalBC() < firstBC + deltaBC) { + while (bcIt != bcs.end() && bcIt.globalBC() < firstBC + deltaBC) { + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + + ++bcIt; + } + if (bcIt == bcs.end()) { + --bcIt; + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + } + } else { + // here bcIt.globalBC() >= firstBC + deltaBC + + while (bcIt != bcs.begin() && bcIt.globalBC() > firstBC + deltaBC) { + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + + --bcIt; + } + } + + int64_t maxBCId = bcIt.globalIndex(); + auto maxGlobalBC = bcIt.globalBC(); + + while (bcIt != bcs.end() && bcIt.globalBC() < lastBC + deltaBC) { + maxBCId = bcIt.globalIndex(); + maxGlobalBC = bcIt.globalBC(); + + ++bcIt; + } + + if (bcIt != bcs.end() && maxBCId >= minBCId) { + T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, (uint64_t)minBCId}; + bcs.copyIndexBindings(slice); + return slice; + } else { + T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId)}, (uint64_t)minBCId}; + bcs.copyIndexBindings(slice); + return slice; + } +} + +template +T getCompatibleBCs(aod::MFTTracks::iterator const& track, aod::Collision const& collOrig, T const& bcs, int deltaBC) +{ + + // define firstBC and lastBC (globalBC of beginning and end of the range, when no shift is applied) + + auto bcIt = collOrig.bc_as(); + // auto timstp = bcIt.timestamp(); + + int64_t firstBC = bcIt.globalBC() + (track.trackTime() - track.trackTimeRes()) / o2::constants::lhc::LHCBunchSpacingNS; + int64_t lastBC = firstBC + 2 * track.trackTimeRes() / o2::constants::lhc::LHCBunchSpacingNS + 1; // to have a delta = 198 BC + + // printf(">>>>>>>>>>>>>>>>>>>>>>>>>>> last-first %lld\n", lastBC-firstBC); + + // int collTimeResInBC = collOrig.collisionTimeRes()/o2::constants::lhc::LHCBunchSpacingNS; + + // int64_t collFirstBC = bcIt.globalBC() + (collOrig.collisionTime() - collOrig.collisionTimeRes())/o2::constants::lhc::LHCBunchSpacingNS; + // int64_t collLastBC = collFirstBC + 2*collOrig.collisionTimeRes()/o2::constants::lhc::LHCBunchSpacingNS +1; + + int64_t minBCId = bcIt.globalIndex(); + uint64_t minGlobalBC = bcIt.globalBC(); + + if ((int64_t)bcIt.globalBC() < firstBC + deltaBC) { + while (bcIt != bcs.end() && (int64_t)bcIt.globalBC() < firstBC + deltaBC) { + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + + ++bcIt; + } + if (bcIt == bcs.end()) { + --bcIt; + // allows to avoid bcIt==bcs.end() in the following + } + // minGlobalBC needs to be >= to firstBC+deltaBC + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + + } else { + // here bcIt.globalBC() >= firstBC + deltaBC + + while (bcIt != bcs.begin() && (int64_t)bcIt.globalBC() >= (int64_t)firstBC + deltaBC) { + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + --bcIt; + } + if (bcIt == bcs.begin() && (int64_t)bcIt.globalBC() >= (int64_t)firstBC + deltaBC) { + minBCId = bcIt.globalIndex(); + minGlobalBC = bcIt.globalBC(); + } + ++bcIt; // retrieve the pointer which gave minBCId and minGlobalBC + if (bcIt == bcs.end()) { + --bcIt; // go back if we got to the end of the list + } + } + + int64_t maxBCId = bcIt.globalIndex(); + uint64_t maxGlobalBC = bcIt.globalBC(); + + if ((int64_t)bcIt.globalBC() > (int64_t)lastBC + deltaBC) { + // the previous minimum is actually bigger than the right boundary + + if (bcIt != bcs.begin()) { + --bcIt; // let's check the previous element in the BC list + if ((int64_t)bcIt.globalBC() < (int64_t)firstBC + deltaBC) // if this previous element is smaller than the left boundary + { + // means that the slice of compatible BCs is empty + + T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE + return slice; // returns an empty slice + } + } + } + + if ((int64_t)bcIt.globalBC() < (int64_t)firstBC + deltaBC) { + // the previous minimum is actually smaller than the right boundary + ++bcIt; + + if (bcIt != bcs.end() && ((int64_t)bcIt.globalBC() > (int64_t)lastBC + deltaBC)) { + // check the following element + + T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE + return slice; // returns an empty slice + } + } + + while (bcIt != bcs.end() && (int64_t)bcIt.globalBC() <= (int64_t)lastBC + deltaBC) { + maxBCId = bcIt.globalIndex(); + maxGlobalBC = bcIt.globalBC(); + + ++bcIt; + } + + if (maxBCId < minBCId) { + if (bcIt == bcs.end()) { + printf("at the end of the bcs iterator %d\n", 1); + } + T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE + return slice; // returns an empty slice + } + + T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, (uint64_t)minBCId}; + bcs.copyIndexBindings(slice); + return slice; +} + +struct matchmftft0 { + Produces BcMft; + struct { + std::vector BCids; + } filler; + + Service ccdb; + + int runNumber = -1; + float Bz = 0; // Magnetic field for MFT + static constexpr double centerMFT[3] = {0, 0, -61.4}; // Field at center of MFT + int count = 0; + o2::parameters::GRPMagField* grpmag = nullptr; + + Configurable strictBCSel{"strictBCSel", false, "force the BC of the match to have FT0A&C signals"}; + Configurable shiftBC{"shiftBC", 0, "shift in BC wrt normal"}; // should be kept at zero except if the time-alignment MFT-FT0C must be redone + + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + + std::vector> channelCoord = {{103.2, 17.8, -813.1}, {76.9, 17.8, -815.9}, {103.1, 44.2, -812.1}, {76.8, 44.2, -814.9}, {103.2, 78.7, -810}, {76.8, 79, -812.9}, {103.2, 105, -807.1}, {76.8, 105.3, -810}, {43.2, 78.8, -815}, {43.2, 105.1, -812.1}, {16.8, 78.9, -815.9}, {16.8, 105.2, -813}, {-16.8, 105.2, -813}, {-16.8, 78.9, -815.9}, {-43.2, 105.1, -812.1}, {-43.2, 78.8, -815}, {-76.8, 105.3, -810}, {-76.8, 79, -812.9}, {-103.2, 105, -807.1}, {-103.2, 78.7, -810}, {-76.8, 44.2, -814.9}, {-103.1, 44.2, -812.1}, {-76.9, 17.8, -815.9}, {-103.2, 17.8, -813.1}, {-103.2, -17.8, -813.1}, {-76.9, -17.8, -815.9}, {-103.1, -44.2, -812.1}, {-76.8, -44.2, -814.9}, {-103.2, -78.7, -810}, {-76.8, -79, -812.9}, {-103.2, -105, -807.1}, {-76.8, -105.3, -810}, {-43.2, -78.8, -815}, {-43.2, -105.1, -812.1}, {-16.8, -78.9, -815.9}, {-16.8, -105.2, -813}, {16.8, -105.2, -813}, {16.8, -78.9, -815.9}, {43.2, -105.1, -812.1}, {43.2, -78.8, -815}, {76.8, -105.3, -810}, {76.8, -79, -812.9}, {103.2, -105, -807.1}, {103.2, -78.7, -810}, {76.8, -44.2, -814.9}, {103.1, -44.2, -812.1}, {76.9, -17.8, -815.9}, {103.2, -17.8, -813.1}, {163, 18.7, -804.1}, {137, 18.9, -808.9}, {163, 45.2, -803.1}, {137, 45.3, -807.9}, {163, 78.6, -800.1}, {137, 79.1, -804.9}, {163, 104.9, -797.2}, {137, 105.4, -801.9}, {103.4, 138, -802}, {102.9, 164, -797.2}, {77.1, 138, -804.9}, {76.6, 164, -800}, {43.3, 139, -807}, {43.2, 165, -802.1}, {16.9, 139, -807.9}, {16.7, 165, -803}, {-16.7, 165, -803}, {-16.9, 139, -807.9}, {-43.2, 165, -802.1}, {-43.3, 139, -807}, {-76.6, 164, -800}, {-77.1, 138, -804.9}, {-102.9, 164, -797.2}, {-103.4, 138, -802}, {-137, 105.4, -801.9}, {-163, 104.9, -797.2}, {-137, 79.1, -804.9}, {-163, 78.6, -800.1}, {-137, 45.3, -807.9}, {-163, 45.2, -803.1}, {-137, 18.9, -808.9}, {-163, 18.7, -804.1}, {-163, -18.7, -804.1}, {-137, -18.9, -808.9}, {-163, -45.2, -803.1}, {-137, -45.3, -807.9}, {-163, -78.6, -800.1}, {-137, -79.1, -804.9}, {-163, -104.9, -797.2}, {-137, -105.4, -801.9}, {-103.4, -138, -802}, {-102.9, -164, -797.2}, {-77.1, -138, -804.9}, {-76.6, -164, -800}, {-43.3, -139, -807}, {-43.2, -165, -802.1}, {-16.9, -139, -807.9}, {-16.7, -165, -803}, {16.7, -165, -803}, {16.9, -139, -807.9}, {43.2, -165, -802.1}, {43.3, -139, -807}, {76.6, -164, -800}, {77.1, -138, -804.9}, {102.9, -164, -797.2}, {103.4, -138, -802}, {137, -105.4, -801.9}, {163, -104.9, -797.2}, {137, -79.1, -804.9}, {163, -78.6, -800.1}, {137, -45.3, -807.9}, {163, -45.2, -803.1}, {137, -18.9, -808.9}, {163, -18.7, -804.1}}; + + HistogramRegistry registry{ + "registry", + {{"UnMatchedTracksXY", "; #it{x} (cm); #it{y} (cm);", {HistType::kTH2F, {{701, -35.05, 35.05}, {701, -35.05, 35.05}}}}, + {"MatchedTracksXY", "; #it{x} (cm); #it{y} (cm);", {HistType::kTH2F, {{701, -35.05, 35.05}, {701, -35.05, 35.05}}}}, + {"AllTracksXY", "; #it{x} (cm); #it{y} (cm);", {HistType::kTH2F, {{701, -35.05, 35.05}, {701, -35.05, 35.05}}}}, + {"DistChannelToProp", "; D (cm); #count", {HistType::kTH1D, {{101, 0, 100}}}}, + {"NchannelsPerBC", "; N_{channelC}; #count", {HistType::kTH1D, {{101, 0, 100}}}}, + {"NgoodBCperTrack", "; N_{goodBC}; #count", {HistType::kTH1D, {{11, 0, 10}}}}, + {"NgoodBCperTrackINDIV", "; N_{goodBC}; #count", {HistType::kTH1D, {{11, 0, 10}}}}, + {"NCompBCwFT0C", "; N_{compBC}; #count", {HistType::kTH1D, {{21, -0.5, 20.5}}}}, + {"NCompBCwFT0s", "; N_{compBC}; #count", {HistType::kTH1D, {{21, -0.5, 20.5}}}}, + {"DiffInBCINDIV", "; indivBC-firstBC (globalBC); #count", {HistType::kTH1I, {{199, 0, 199}}}}, + {"DiffInBC", "; goodBC-firstBC (globalBC); #count", {HistType::kTH1I, {{199, 0, 199}}}}}}; + + void init(InitContext const&) + { + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + } + + void initCCDB(ExtBCs::iterator const& bc) + { + + if (runNumber == bc.runNumber()) { + return; + } + grpmag = ccdb->getForTimeStamp(grpmagPath, bc.timestamp()); + LOG(info) << "Setting magnetic field to current " << grpmag->getL3Current() + << " A for run " << bc.runNumber() + << " from its GRPMagField CCDB object"; + o2::base::Propagator::initFieldFromGRP(grpmag); // for some reason this is necessary for the next next line + runNumber = bc.runNumber(); + + o2::field::MagneticField* field = static_cast(TGeoGlobalMagField::Instance()->GetField()); + + Bz = field->getBz(centerMFT); // gives error if the propagator is not initFielded + LOG(info) << "The field at the center of the MFT is Bz = " << Bz; + } + + bool isInFT0Acc(double x, double y) + { + // returns true if the propagated x and y positions are in an active zone of the FT0-C, false if they in a dead zone + + if ((abs(x) < 6.365) && (abs(y) < 6.555)) { + // track outside the FT0-C acceptance (in the central hole) + return false; + } + + if (((x > -12.75) && (x < -11.85)) || ((x > -6.55) && (x < -5.75)) || ((x > -0.35) && (x < 0.45)) || ((x > 5.75) && (x < 6.55)) || ((x > 11.85) && (x < 12.75))) { + // track outside the FT0-C acceptance (in the vertical line holes) + return false; + } + + if (((y > -12.95) && (y < -11.95)) || ((y > -6.65) && (y < -5.85)) || ((y > -0.55) && (y < 0.45)) || ((y > 5.75) && (y < 6.65)) || ((y > 11.95) && (y < 12.85))) { + // track outside the FT0-C acceptance (in the horizontal line holes) + return false; + } + + return true; + } + + void processMFT(aod::MFTTracks const& mfttracks, + aod::Collisions const&, ExtBCs const& bcs, + aod::FT0s const&) + { + initCCDB(bcs.begin()); + + int i = 0; // counts the number of channels having non-zero amplitude + // for a particular BC + double D = 0.0; // distance between (xe,ye,ze) and (xc,yc,zc) + double minD; + double globalMinD; + + for (auto& track : mfttracks) { + filler.BCids.clear(); + globalMinD = 999.; // minimum D for all BC + ExtBCs::iterator closestBC; // compatible BC with the D the smallest + // beware: there could be several BC with the same smallest D + // not a very useful variable + + if (!track.has_collision()) { + BcMft(track.globalIndex(), filler.BCids); // empty + continue; + } + auto collOrig = track.collision(); + + auto bcSlice = getCompatibleBCs(track, collOrig, bcs, shiftBC); + + // firstBC= global BC of the beginning of the ROF (shifted by shiftBC) + int64_t firstBC = collOrig.bc_as().globalBC() + (track.trackTime() - track.trackTimeRes()) / o2::constants::lhc::LHCBunchSpacingNS + shiftBC; + + bool rofHasBoth = false; // ROF with both FT0C and FT0A signal in the same BC + + std::vector v1; // Temporary null vector for the computation of the covariance matrix + SMatrix55 tcovs(v1.begin(), v1.end()); + SMatrix5 tpars(track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt()); + + o2::track::TrackParCovFwd trackPar{track.z(), tpars, tcovs, track.chi2()}; + + // we propagate the MFT track to the mean z position of FT0-C + // getTrackPar() doesn't work because mft tracks don't have alpha + trackPar.propagateToZhelix(-82.6, Bz); // z in cm + + if (!isInFT0Acc(trackPar.getX(), trackPar.getY())) { + // track outside the FT0-C acceptance + BcMft(track.globalIndex(), filler.BCids); // empty + continue; + } + + std::vector goodBC; // contains the BCs matched with the current MFT track + int nCompBCwft0C = 0; + int nCompBCwft0s = 0; // Number of compatible BCs with FT0A AND C signals + + bool hasft0A = false; + bool hasft0C = false; + for (auto& bc : bcSlice) { + hasft0C = false; + hasft0A = false; + // printf("----------bcId %lld\n", bc.globalIndex()); + if (!bc.has_ft0s()) { + continue; + } + + auto ft0s = bc.ft0s(); + i = 0; // reinitialise + D = 0.0; + minD = 999.9; + for (auto const& ft0 : ft0s) { + // printf("---------ft0.bcId %d\n", ft0.bcId()); + if (ft0.channelA().size() > 0) { + // BC with signals in FT0A + hasft0A = true; + } + + if (ft0.channelC().size() > 0) { + hasft0C = true; + } + for (auto channelId : ft0.channelC()) { + + std::vector Xc = channelCoord[channelId]; //(xc,yc,zc) coordinates + // D in cm + D = sqrt(pow(Xc[0] * 0.1 - trackPar.getX(), 2) + pow(Xc[1] * 0.1 - trackPar.getY(), 2) + pow(Xc[2] * 0.1 - 1.87 - trackPar.getZ(), 2)); + // printf("----channelId %u, D %f, n %d\n", channelId, D, n);//should be between 96 and 207 + if (D < minD) { + minD = D; + } + + registry.fill(HIST("DistChannelToProp"), D); + } + + i += ft0.channelC().size(); + } + + registry.fill(HIST("NchannelsPerBC"), i); + if (hasft0C) { + nCompBCwft0C++; // number of compatible BCs that have ft0-C signal + } + + //----------------------- BC selection here ------------------------ + // if strictBCSel true we are only considering BC with signals from both FT0A and FT0C + if (!(hasft0A && hasft0C) && strictBCSel) { + continue; + // we go to the next BC + } + nCompBCwft0s++; + if (hasft0A && hasft0C) { + rofHasBoth = true; + } + + //----------------------- end of BC selection ------------------------ + + if (minD < 2) // 20 mm + { + goodBC.push_back(bc); // goodBC is a vector of bc + filler.BCids.emplace_back(bc.globalIndex()); + } + if (minD < globalMinD) { + globalMinD = minD; + closestBC = bc; + } + } + + if (!rofHasBoth) { + // there isn't a coincidence of FT0A and C inside the considered MFT ROF + // MFT track is probably noise, we don't select it + filler.BCids.clear(); + BcMft(track.globalIndex(), filler.BCids); // empty + continue; + } + registry.fill(HIST("NgoodBCperTrack"), goodBC.size()); + if (goodBC.size() == 0) { + registry.fill(HIST("UnMatchedTracksXY"), trackPar.getX(), trackPar.getY()); + } + if (goodBC.size() > 0) { + registry.fill(HIST("MatchedTracksXY"), trackPar.getX(), trackPar.getY()); + int64_t diff = goodBC[0].globalBC() - firstBC; + registry.fill(HIST("DiffInBC"), diff); + } + registry.fill(HIST("AllTracksXY"), trackPar.getX(), trackPar.getY()); + registry.fill(HIST("NCompBCwFT0C"), nCompBCwft0C); + registry.fill(HIST("NCompBCwFT0s"), nCompBCwft0s); + + if (nCompBCwft0s == 1) { + registry.fill(HIST("NgoodBCperTrackINDIV"), goodBC.size()); + + // position of the goodBC in the ROF for isolated colliding BCs + if (goodBC.size() > 0) { + int64_t diff = goodBC[0].globalBC() - firstBC; + registry.fill(HIST("DiffInBCINDIV"), diff); + } + } + + BcMft(track.globalIndex(), filler.BCids); + } // loop of mfttracks + } + PROCESS_SWITCH(matchmftft0, processMFT, "Process MFT tracks with collisions", true); +}; + +struct checkmatchinmc { + // checks if the matching works as expected in MC + // only doprocessMFTMCcheck==true if you are analysing MC + + HistogramRegistry registryMC{ + "registryMC", + {}}; + + void init(InitContext const&) + { + if (doprocessMFTMCcheck) { + registryMC.add({"TrackIsMatched", "; isMFTTrackMatched; #count", {HistType::kTH1I, {{2, 0, 2}}}}); + registryMC.add({"DiffInBCTrue", "; goodBC-trueBC (globalBC); #count", {HistType::kTH1I, {{800, -400, 400}}}}); + registryMC.add({"TrueBCAmongMatched", "; isTrueBCAmongMatchedOnes; #count", {HistType::kTH1D, {{2, 0, 2}}}}); + } + } + + using MFTTracksLabeledWithFT0 = soa::Join; + + void processMFTMCcheck(MFTTracksLabeledWithFT0 const& mfttracks, + aod::McCollisions const&, ExtBCs const&, aod::McParticles const&) + { + + for (auto& mfttrack : mfttracks) { + + if (!mfttrack.has_bcs()) // mft tracks having a match in FT0-C + { + registryMC.fill(HIST("TrackIsMatched"), 0); + continue; + } + + registryMC.fill(HIST("TrackIsMatched"), 1); // around 50% of all MFT tracks are matched with FT0-C in data + // around 90% of MFT tracks falling in the active FT0-C regions are matched + if (!mfttrack.has_mcParticle()) { + continue; + } + + o2::aod::McParticle particle = mfttrack.mcParticle(); + int64_t trueMFTBC = particle.mcCollision().bc_as().globalBC(); + ; + bool isTrueBCAmongMatchedOnes = false; + + for (auto& bc : mfttrack.bcs_as()) { // + int64_t bcDiffTrue = bc.globalBC() - trueMFTBC; // difference between the muon's BC and the MFT track's BC + registryMC.fill(HIST("DiffInBCTrue"), bcDiffTrue); + if (bcDiffTrue == 0) { + isTrueBCAmongMatchedOnes = true; + } + } + if (isTrueBCAmongMatchedOnes) { + registryMC.fill(HIST("TrueBCAmongMatched"), 1); + } else { + registryMC.fill(HIST("TrueBCAmongMatched"), 0); + } + } + } + PROCESS_SWITCH(checkmatchinmc, processMFTMCcheck, "Process MFT tracks and check matching with MC information", false); + + void processDummy(aod::Collisions const&) + { + // do nothing + } + PROCESS_SWITCH(checkmatchinmc, processDummy, "Do nothing if not MC", true); +}; + +WorkflowSpec + defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/Common/TableProducer/multiplicityExtraTable.cxx b/Common/TableProducer/multiplicityExtraTable.cxx index cc37a39e34b..075b0d108ee 100644 --- a/Common/TableProducer/multiplicityExtraTable.cxx +++ b/Common/TableProducer/multiplicityExtraTable.cxx @@ -30,9 +30,12 @@ using BCPattern = std::bitset; const int nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches; struct MultiplicityExtraTable { - Produces multBC; + Produces multBC; Produces multNeigh; + Produces mult2bc; + Produces bc2mult; + // Allow for downscaling of BC table for less space use in derived data Configurable bcDownscaleFactor{"bcDownscaleFactor", 2, "Downscale factor for BC table (0: save nothing, 1: save all)"}; Configurable minFT0CforBCTable{"minFT0CforBCTable", 25.0f, "Minimum FT0C amplitude to fill BC table to reduce data"}; @@ -59,117 +62,159 @@ struct MultiplicityExtraTable { using BCsWithRun3Matchings = soa::Join; - void processBCs(BCsWithRun3Matchings::iterator const& bc, aod::FV0As const&, aod::FT0s const&, aod::FDDs const&, aod::Zdcs const&) + void processBCs(BCsWithRun3Matchings const& bcs, aod::FV0As const&, aod::FT0s const&, aod::FDDs const&, aod::Zdcs const&, aod::Collisions const& collisions) { - // downscale if requested to do so - if (bcDownscaleFactor < 1.f && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > bcDownscaleFactor) { - return; - } + //+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+ + // determine saved BCs and corresponding new BC table index + std::vector newBCindex(bcs.size()); + std::vector bc2multArray(bcs.size()); + int atIndex = 0; + for (const auto& bc : bcs) { + newBCindex[bc.globalIndex()] = -1; + bc2multArray[bc.globalIndex()] = -1; + + // downscale if requested to do so + if (bcDownscaleFactor < 1.f && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > bcDownscaleFactor) { + continue; + } - bool Tvx = false; - bool isFV0OrA = false; - float multFT0C = 0.f; - float multFT0A = 0.f; - float multFV0A = 0.f; - float multFDDA = 0.f; - float multFDDC = 0.f; - - // ZDC amplitudes - float multZEM1 = -1.f; - float multZEM2 = -1.f; - float multZNA = -1.f; - float multZNC = -1.f; - float multZPA = -1.f; - float multZPC = -1.f; - - uint8_t multFT0TriggerBits = 0; - uint8_t multFV0TriggerBits = 0; - uint8_t multFDDTriggerBits = 0; - uint64_t multBCTriggerMask = bc.triggerMask(); - - // initialize - from Arvind - newRunNumber = bc.runNumber(); - int localBC = bc.globalBC() % nBCsPerOrbit; - - if (newRunNumber != oldRunNumber) { - auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, newRunNumber); - auto ts = soreor.first; - - LOG(info) << " newRunNumber " << newRunNumber << " time stamp " << ts; - oldRunNumber = newRunNumber; - auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", ts); - CollidingBunch = grplhcif->getBunchFilling().getBCPattern(); - } // new run number - - bool collidingBC = CollidingBunch.test(localBC); - - if (bc.has_ft0()) { - auto ft0 = bc.ft0(); - std::bitset<8> triggers = ft0.triggerMask(); - Tvx = triggers[o2::fit::Triggers::bitVertex]; - multFT0TriggerBits = static_cast(triggers.to_ulong()); - - // calculate T0 charge - for (auto amplitude : ft0.amplitudeA()) { - multFT0A += amplitude; + float multFT0C = 0.f; + if (bc.has_ft0()) { + auto ft0 = bc.ft0(); + for (auto amplitude : ft0.amplitudeC()) { + multFT0C += amplitude; + } + } else { + multFT0C = -999.0f; } - for (auto amplitude : ft0.amplitudeC()) { - multFT0C += amplitude; + + if (multFT0C < minFT0CforBCTable) { + continue; // skip this event } - } else { - multFT0A = -999.0f; - multFT0C = -999.0f; + newBCindex[bc.globalIndex()] = atIndex++; } - if (bc.has_fv0a()) { - auto fv0 = bc.fv0a(); - std::bitset<8> fV0Triggers = fv0.triggerMask(); - multFV0TriggerBits = static_cast(fV0Triggers.to_ulong()); + //+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+ - for (auto amplitude : fv0.amplitude()) { - multFV0A += amplitude; - } - isFV0OrA = fV0Triggers[o2::fit::Triggers::bitA]; - } else { - multFV0A = -999.0f; + //+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+ + // interlink: collision -> valid BC, BC -> collision + for (const auto& collision : collisions) { + mult2bc(newBCindex[collision.bcId()]); + bc2multArray[collision.bcId()] = collision.globalIndex(); } + //+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+-<*>-+ - if (bc.has_fdd()) { - auto fdd = bc.fdd(); - std::bitset<8> fFDDTriggers = fdd.triggerMask(); - multFDDTriggerBits = static_cast(fFDDTriggers.to_ulong()); + for (const auto& bc : bcs) { + if (newBCindex[bc.globalIndex()] < 0) { + continue; // don't keep if low mult or downsampled out + } - for (auto amplitude : fdd.chargeA()) { - multFDDA += amplitude; + bool Tvx = false; + bool isFV0OrA = false; + float multFT0C = 0.f; + float multFT0A = 0.f; + float multFV0A = 0.f; + float multFDDA = 0.f; + float multFDDC = 0.f; + + // ZDC amplitudes + float multZEM1 = -1.f; + float multZEM2 = -1.f; + float multZNA = -1.f; + float multZNC = -1.f; + float multZPA = -1.f; + float multZPC = -1.f; + + float posZFT0 = -1e+3; + bool posZFT0valid = false; + + uint8_t multFT0TriggerBits = 0; + uint8_t multFV0TriggerBits = 0; + uint8_t multFDDTriggerBits = 0; + uint64_t multBCTriggerMask = bc.triggerMask(); + + // initialize - from Arvind + newRunNumber = bc.runNumber(); + int localBC = bc.globalBC() % nBCsPerOrbit; + + if (newRunNumber != oldRunNumber) { + auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, newRunNumber); + auto ts = soreor.first; + + LOG(info) << " newRunNumber " << newRunNumber << " time stamp " << ts; + oldRunNumber = newRunNumber; + auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", ts); + CollidingBunch = grplhcif->getBunchFilling().getBCPattern(); + } // new run number + + bool collidingBC = CollidingBunch.test(localBC); + + if (bc.has_ft0()) { + const auto& ft0 = bc.ft0(); + std::bitset<8> triggers = ft0.triggerMask(); + Tvx = triggers[o2::fit::Triggers::bitVertex]; + multFT0TriggerBits = static_cast(triggers.to_ulong()); + + // calculate T0 charge + for (auto amplitude : ft0.amplitudeA()) { + multFT0A += amplitude; + } + for (auto amplitude : ft0.amplitudeC()) { + multFT0C += amplitude; + } + posZFT0 = ft0.posZ(); + posZFT0valid = ft0.isValidTime(); + } else { + multFT0A = -999.0f; + multFT0C = -999.0f; } - for (auto amplitude : fdd.chargeC()) { - multFDDC += amplitude; + if (bc.has_fv0a()) { + auto fv0 = bc.fv0a(); + std::bitset<8> fV0Triggers = fv0.triggerMask(); + multFV0TriggerBits = static_cast(fV0Triggers.to_ulong()); + + for (auto amplitude : fv0.amplitude()) { + multFV0A += amplitude; + } + isFV0OrA = fV0Triggers[o2::fit::Triggers::bitA]; + } else { + multFV0A = -999.0f; } - } else { - multFDDA = -999.0f; - multFDDC = -999.0f; - } - if (bc.has_zdc()) { - multZNA = bc.zdc().amplitudeZNA(); - multZNC = bc.zdc().amplitudeZNC(); - multZEM1 = bc.zdc().amplitudeZEM1(); - multZEM2 = bc.zdc().amplitudeZEM2(); - multZPA = bc.zdc().amplitudeZPA(); - multZPC = bc.zdc().amplitudeZPC(); - } else { - multZNA = -999.f; - multZNC = -999.f; - multZEM1 = -999.f; - multZEM2 = -999.f; - multZPA = -999.f; - multZPC = -999.f; - } + if (bc.has_fdd()) { + auto fdd = bc.fdd(); + std::bitset<8> fFDDTriggers = fdd.triggerMask(); + multFDDTriggerBits = static_cast(fFDDTriggers.to_ulong()); + + for (auto amplitude : fdd.chargeA()) { + multFDDA += amplitude; + } + for (auto amplitude : fdd.chargeC()) { + multFDDC += amplitude; + } + } else { + multFDDA = -999.0f; + multFDDC = -999.0f; + } - if (multFT0C < minFT0CforBCTable) { - return; // skip this event - } + if (bc.has_zdc()) { + multZNA = bc.zdc().amplitudeZNA(); + multZNC = bc.zdc().amplitudeZNC(); + multZEM1 = bc.zdc().amplitudeZEM1(); + multZEM2 = bc.zdc().amplitudeZEM2(); + multZPA = bc.zdc().amplitudeZPA(); + multZPC = bc.zdc().amplitudeZPC(); + } else { + multZNA = -999.f; + multZNC = -999.f; + multZEM1 = -999.f; + multZEM2 = -999.f; + multZPA = -999.f; + multZPC = -999.f; + } - multBC(multFT0A, multFT0C, multFV0A, multFDDA, multFDDC, multZNA, multZNC, multZEM1, multZEM2, multZPA, multZPC, Tvx, isFV0OrA, multFV0TriggerBits, multFT0TriggerBits, multFDDTriggerBits, multBCTriggerMask, collidingBC); + bc2mult(bc2multArray[bc.globalIndex()]); + multBC(multFT0A, multFT0C, posZFT0, posZFT0valid, multFV0A, multFDDA, multFDDC, multZNA, multZNC, multZEM1, multZEM2, multZPA, multZPC, Tvx, isFV0OrA, multFV0TriggerBits, multFT0TriggerBits, multFDDTriggerBits, multBCTriggerMask, collidingBC); + } } void processCollisionNeighbors(aod::Collisions const& collisions) diff --git a/Common/TableProducer/multiplicityTable.cxx b/Common/TableProducer/multiplicityTable.cxx index 9ca40a47e19..8991c38cd10 100644 --- a/Common/TableProducer/multiplicityTable.cxx +++ b/Common/TableProducer/multiplicityTable.cxx @@ -43,7 +43,7 @@ static constexpr int kFV0MultZeqs = 9; static constexpr int kFT0MultZeqs = 10; static constexpr int kFDDMultZeqs = 11; static constexpr int kPVMultZeqs = 12; -static constexpr int kMultsExtraMC = 13; +static constexpr int kMultMCExtras = 13; static constexpr int nTables = 14; // Checking that the Zeq tables are after the normal ones @@ -66,7 +66,7 @@ static const std::vector tableNames{"FV0Mults", // 0 "FT0MultZeqs", // 10 "FDDMultZeqs", // 11 "PVMultZeqs", // 12 - "MultsExtraMC"}; // 13 + "MultMCExtras"}; // 13 static const std::vector parameterNames{"Enable"}; static const int defaultParameters[nTables][nParameters]{{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}}; @@ -85,7 +85,8 @@ struct MultiplicityTable { Produces tableFT0Zeqs; // 10 Produces tableFDDZeqs; // 11 Produces tablePVZeqs; // 12 - Produces tableExtraMc; // 13 + Produces tableExtraMc; // 13 + Produces tableExtraMc2Mults; Produces multsGlobal; // Not accounted for, produced based on process function processGlobalTrackingCounters // For vertex-Z corrections in calibration @@ -163,10 +164,11 @@ struct MultiplicityTable { } } // Handle the custom cases. - if (tEnabled[kMultsExtraMC]) { - if (enabledTables->get(tableNames[kMultsExtraMC].c_str(), "Enable") == -1) { + if (tEnabled[kMultMCExtras]) { + if (enabledTables->get(tableNames[kMultMCExtras].c_str(), "Enable") == -1) { doprocessMC.value = true; - LOG(info) << "Enabling MC processing due to " << tableNames[kMultsExtraMC] << " table being enabled."; + doprocessMC2Mults.value = true; + LOG(info) << "Enabling MC processing due to " << tableNames[kMultMCExtras] << " table being enabled."; } } @@ -335,7 +337,7 @@ struct MultiplicityTable { case kPVMultZeqs: // Equalized multiplicity for PV tablePVZeqs.reserve(collisions.size()); break; - case kMultsExtraMC: // MC extra information (nothing to do in the data) + case kMultMCExtras: // MC extra information (nothing to do in the data) break; default: LOG(fatal) << "Unknown table requested: " << i; @@ -567,7 +569,7 @@ struct MultiplicityTable { tableExtra(collision.numContrib(), collision.chi2(), collision.collisionTimeRes(), mRunNumber, collision.posZ(), collision.sel8(), nHasITS, nHasTPC, nHasTOF, nHasTRD, nITSonly, nTPConly, nITSTPC, - nAllTracksTPCOnly, nAllTracksITSTPC, bcNumber, collision.trackOccupancyInTimeRange()); + nAllTracksTPCOnly, nAllTracksITSTPC, collision.trackOccupancyInTimeRange()); } break; case kMultSelections: // Multiplicity selections { @@ -609,7 +611,7 @@ struct MultiplicityTable { } tablePVZeqs(multZeqNContribs); } break; - case kMultsExtraMC: // MC only (nothing to do) + case kMultMCExtras: // MC only (nothing to do) { } break; default: // Default @@ -627,7 +629,7 @@ struct MultiplicityTable { Filter mcParticleFilter = (aod::mcparticle::eta < 4.9f) && (aod::mcparticle::eta > -3.3f); using mcParticlesFiltered = soa::Filtered; - void processMC(aod::McCollision const&, mcParticlesFiltered const& mcParticles) + void processMC(aod::McCollision const& mcCollision, mcParticlesFiltered const& mcParticles) { int multFT0A = 0; int multFT0C = 0; @@ -662,7 +664,12 @@ struct MultiplicityTable { if (3.5 < mcPart.eta() && mcPart.eta() < 4.9) multFT0A++; } - tableExtraMc(multFT0A, multFT0C, multBarrelEta05, multBarrelEta08, multBarrelEta10); + tableExtraMc(multFT0A, multFT0C, multBarrelEta05, multBarrelEta08, multBarrelEta10, mcCollision.posZ()); + } + + void processMC2Mults(soa::Join::iterator const& collision) + { + tableExtraMc2Mults(collision.mcCollisionId()); // interlink } Configurable min_pt_globaltrack{"min_pt_globaltrack", 0.15, "min. pT for global tracks"}; @@ -715,6 +722,7 @@ struct MultiplicityTable { PROCESS_SWITCH(MultiplicityTable, processRun3, "Produce Run 3 multiplicity tables", true); PROCESS_SWITCH(MultiplicityTable, processGlobalTrackingCounters, "Produce Run 3 global counters", false); PROCESS_SWITCH(MultiplicityTable, processMC, "Produce MC multiplicity tables", false); + PROCESS_SWITCH(MultiplicityTable, processMC2Mults, "Produce MC -> Mult map", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/Common/TableProducer/timestamp.cxx b/Common/TableProducer/timestamp.cxx index 3860b92492e..ceaa8acd25d 100644 --- a/Common/TableProducer/timestamp.cxx +++ b/Common/TableProducer/timestamp.cxx @@ -35,9 +35,12 @@ 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 fatalOnInvalidTimestamp{"fatalOnInvalidTimestamp", false, "Generate fatal error for invalid timestamps"}; std::map mapRunToOrbitReset; /// Cache of orbit reset timestamps + std::map> mapRunToRunDuration; /// Cache of run duration timestamps int lastRunNumber = 0; /// Last run number processed int64_t orbitResetTimestamp = 0; /// Orbit-reset timestamp in us + std::pair runDuration; /// Pair of SOR and EOR timestamps // Configurables Configurable verbose{"verbose", false, "verbose mode"}; @@ -75,11 +78,12 @@ struct TimestampTask { } else if (mapRunToOrbitReset.count(runNumber)) { // The run number was already requested before: getting it from cache! LOGF(debug, "Getting orbit-reset timestamp from cache"); orbitResetTimestamp = mapRunToOrbitReset[runNumber]; + runDuration = mapRunToRunDuration[runNumber]; } else { // The run was not requested before: need to acccess CCDB! LOGF(debug, "Getting start-of-run and end-of-run timestamps from CCDB"); - auto timestamps = ccdb->getRunDuration(runNumber, true); /// fatalise if timestamps are not found - int64_t sorTimestamp = timestamps.first; // timestamp of the SOR in ms - int64_t eorTimestamp = timestamps.second; // timestamp of the EOR in ms + runDuration = ccdb->getRunDuration(runNumber, true); /// fatalise if timestamps are not found + int64_t sorTimestamp = runDuration.first; // timestamp of the SOR/SOX/STF in ms + int64_t eorTimestamp = runDuration.second; // timestamp of the EOR/EOX/ETF in ms const bool isUnanchoredRun3MC = runNumber >= 300000 && runNumber < 500000; if (isRun2MC.value == 1 || isUnanchoredRun3MC) { @@ -94,7 +98,7 @@ struct TimestampTask { } else { // sometimes orbit is reset after SOR. Using EOR timestamps for orbitReset query is more reliable LOGF(debug, "Getting orbit-reset timestamp using end-of-run timestamp from CCDB"); - auto ctp = ccdb->getForTimeStamp>(orbit_reset_path.value.data(), eorTimestamp); + auto ctp = ccdb->getForTimeStamp>(orbit_reset_path.value.data(), eorTimestamp / 2 + sorTimestamp / 2); orbitResetTimestamp = (*ctp)[0]; } @@ -104,14 +108,22 @@ struct TimestampTask { if (!check.second) { LOGF(fatal, "Run number %i already existed with a orbit-reset timestamp of %llu", runNumber, check.first->second); } - LOGF(info, "Add new run number %i with orbit-reset timestamp %llu to cache", runNumber, orbitResetTimestamp); + mapRunToRunDuration[runNumber] = runDuration; + LOGF(info, "Add new run number %i with orbit-reset timestamp %llu, SOR: %llu, EOR: %llu to cache", runNumber, orbitResetTimestamp, runDuration.first, runDuration.second); } if (verbose.value) { LOGF(info, "Orbit-reset timestamp for run number %i found: %llu us", runNumber, orbitResetTimestamp); } - - timestampTable((orbitResetTimestamp + int64_t(bc.globalBC() * o2::constants::lhc::LHCBunchSpacingNS * 1e-3)) / 1000); // us -> ms + int64_t timestamp{(orbitResetTimestamp + int64_t(bc.globalBC() * o2::constants::lhc::LHCBunchSpacingNS * 1e-3)) / 1000}; // us -> ms + if (timestamp < runDuration.first || timestamp > runDuration.second) { + if (fatalOnInvalidTimestamp.value) { + LOGF(fatal, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second); + } else { + LOGF(warn, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second); + } + } + timestampTable(timestamp); } }; diff --git a/Common/Tasks/centralityStudy.cxx b/Common/Tasks/centralityStudy.cxx index f24fa99f9e2..1ba72958a37 100644 --- a/Common/Tasks/centralityStudy.cxx +++ b/Common/Tasks/centralityStudy.cxx @@ -203,7 +203,7 @@ struct centralityStudy { genericProcessCollision(collision); } - void processBCs(aod::MultsBC::iterator const& multbc) + void processBCs(aod::MultBCs::iterator const& multbc) { // process BCs, calculate FT0C distribution // conditionals suggested by FIT team (Jacek O. et al) diff --git a/Common/Tasks/multiplicityQa.cxx b/Common/Tasks/multiplicityQa.cxx index 72fc827606a..3bf0f769b79 100644 --- a/Common/Tasks/multiplicityQa.cxx +++ b/Common/Tasks/multiplicityQa.cxx @@ -402,7 +402,7 @@ struct MultiplicityQa { histos.fill(HIST("multiplicityQa/h2dFT0MVsNchT0M"), nchFT0, biggestFT0); } - void processFIT(aod::MultsBC const& multsdebug) + void processFIT(aod::MultBCs const& multsdebug) { for (auto& mult : multsdebug) { histos.fill(HIST("multiplicityQa/hIsolatedFT0A"), mult.multBCFT0A()); diff --git a/Common/Tasks/qVectorsCorrection.cxx b/Common/Tasks/qVectorsCorrection.cxx index 5c3c8af7a31..bc9c555e154 100644 --- a/Common/Tasks/qVectorsCorrection.cxx +++ b/Common/Tasks/qVectorsCorrection.cxx @@ -73,6 +73,8 @@ struct qVectorsCorrection { Configurable cfgQAAll{"cfgQAAll", false, "draw all q-vector steps"}; Configurable cfgQAFinal{"cfgQAFinal", false, "draw final q-vector steps"}; + Configurable cfgQAFlowStudy{"cfgQAFlowStudy", false, "configurable for flow study"}; + Configurable cfgQAOccupancyStudy{"cfgQAOccupancyStudy", false, "configurable for occupancy study"}; Configurable cfgMinPt{"cfgMinPt", 0.15, "Minimum transverse momentum for charged track"}; Configurable cfgMaxEta{"cfgMaxEta", 0.8, "Maximum pseudorapidiy for charged track"}; @@ -90,6 +92,7 @@ struct qVectorsCorrection { ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, ""}; ConfigurableAxis cfgaxisCentMerged{"cfgaxisCentMerged", {20, 0, 100}, ""}; ConfigurableAxis cfgaxisAzimuth{"cfgaxisAzimuth", {72, 0, 2.0 * constants::math::PI}, ""}; + ConfigurableAxis cfgaxisOccupancy{"cfgaxisOccupancy", {VARIABLE_WIDTH, -1, 0, 100, 500, 1000, 2000, 3000, 4000, 5000, 10000, 99999}, ""}; // Helper variables. EventPlaneHelper helperEP; @@ -169,6 +172,8 @@ struct qVectorsCorrection { AxisSpec axisPt{cfgaxispt, "trasverse momentum"}; AxisSpec axisCentMerged{cfgaxisCentMerged, "merged centrality"}; AxisSpec axisAzimuth{cfgaxisAzimuth, "relative azimuthal angle"}; + AxisSpec axisOccupancy{cfgaxisOccupancy, "Occupancy"}; + histosQA.add("histCentFull", "Centrality distribution for valid events", HistType::kTH1F, {axisCent}); @@ -181,11 +186,23 @@ struct qVectorsCorrection { histosQA.add(Form("histEvtPlRefAUncorV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); histosQA.add(Form("histEvtPlRefBUncorV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + if (cfgQAOccupancyStudy) { + histosQA.add(Form("histQvecOccUncorV%d", cfgnMods->at(i)), "", {HistType::kTHnSparseF, {axisQvecF, axisQvecF, axisCent, axisOccupancy}}); + histosQA.add(Form("histQvecRefAOccUncorV%d", cfgnMods->at(i)), "", {HistType::kTHnSparseF, {axisQvecF, axisQvecF, axisCent, axisOccupancy}}); + histosQA.add(Form("histQvecRefBOccUncorV%d", cfgnMods->at(i)), "", {HistType::kTHnSparseF, {axisQvecF, axisQvecF, axisCent, axisOccupancy}}); + } + if (cfgQAFinal) { histosQA.add(Form("histQvecFinalV%d", cfgnMods->at(i)), "", {HistType::kTH3F, {axisQvec, axisQvec, axisCent}}); histosQA.add(Form("histQvecRefAFinalV%d", cfgnMods->at(i)), "", {HistType::kTH3F, {axisQvec, axisQvec, axisCent}}); histosQA.add(Form("histQvecRefBFinalV%d", cfgnMods->at(i)), "", {HistType::kTH3F, {axisQvec, axisQvec, axisCent}}); + if (cfgQAOccupancyStudy) { + histosQA.add(Form("histQvecOccFinalV%d", cfgnMods->at(i)), "", {HistType::kTHnSparseF, {axisQvecF, axisQvecF, axisCent, axisOccupancy}}); + histosQA.add(Form("histQvecRefAOccFinalV%d", cfgnMods->at(i)), "", {HistType::kTHnSparseF, {axisQvecF, axisQvecF, axisCent, axisOccupancy}}); + histosQA.add(Form("histQvecRefBOccFinalV%d", cfgnMods->at(i)), "", {HistType::kTHnSparseF, {axisQvecF, axisQvecF, axisCent, axisOccupancy}}); + } + histosQA.add(Form("histQvecRes_SigRefAV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisQvecF, axisCent}}); histosQA.add(Form("histQvecRes_SigRefBV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisQvecF, axisCent}}); histosQA.add(Form("histQvecRes_RefARefBV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisQvecF, axisCent}}); @@ -303,9 +320,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[DetId] > 1e-8) { histosQA.fill(HIST("histQvecUncorV2"), vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], vec.cent()); histosQA.fill(HIST("histEvtPlUncorV2"), helperEP.GetEventPlane(vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecOccUncorV2"), vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecFinalV2"), vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlFinalV2"), helperEP.GetEventPlane(vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecOccFinalV2"), vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRectrV2"), vec.qvecRe()[DetInd + 1], vec.qvecIm()[DetInd + 1], vec.cent()); histosQA.fill(HIST("histQvecTwistV2"), vec.qvecRe()[DetInd + 2], vec.qvecIm()[DetInd + 2], vec.cent()); @@ -318,9 +341,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[RefAId] > 1e-8) { histosQA.fill(HIST("histQvecRefAUncorV2"), vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], vec.cent()); histosQA.fill(HIST("histEvtPlRefAUncorV2"), helperEP.GetEventPlane(vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefAOccUncorV2"), vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecRefAFinalV2"), vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlRefAFinalV2"), helperEP.GetEventPlane(vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefAOccFinalV2"), vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRefARectrV2"), vec.qvecRe()[RefAInd + 1], vec.qvecIm()[RefAInd + 1], vec.cent()); histosQA.fill(HIST("histQvecRefATwistV2"), vec.qvecRe()[RefAInd + 2], vec.qvecIm()[RefAInd + 2], vec.cent()); @@ -333,9 +362,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[RefBId] > 1e-8) { histosQA.fill(HIST("histQvecRefBUncorV2"), vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], vec.cent()); histosQA.fill(HIST("histEvtPlRefBUncorV2"), helperEP.GetEventPlane(vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefBOccUncorV2"), vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecRefBFinalV2"), vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlRefBFinalV2"), helperEP.GetEventPlane(vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefBOccFinalV2"), vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRefBRectrV2"), vec.qvecRe()[RefBInd + 1], vec.qvecIm()[RefBInd + 1], vec.cent()); histosQA.fill(HIST("histQvecRefBTwistV2"), vec.qvecRe()[RefBInd + 2], vec.qvecIm()[RefBInd + 2], vec.cent()); @@ -358,7 +393,13 @@ struct qVectorsCorrection { if (vec.qvecAmp()[DetId] > 1e-8) { histosQA.fill(HIST("histQvecUncorV3"), vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], vec.cent()); histosQA.fill(HIST("histEvtPlUncorV3"), helperEP.GetEventPlane(vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecOccUncorV3"), vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecOccFinalV3"), vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } histosQA.fill(HIST("histQvecFinalV3"), vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlFinalV3"), helperEP.GetEventPlane(vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], nmode), vec.cent()); if (cfgQAAll) { @@ -373,9 +414,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[RefAId] > 1e-8) { histosQA.fill(HIST("histQvecRefAUncorV3"), vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], vec.cent()); histosQA.fill(HIST("histEvtPlRefAUncorV3"), helperEP.GetEventPlane(vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefAOccUncorV3"), vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecRefAFinalV3"), vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlRefAFinalV3"), helperEP.GetEventPlane(vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefAOccFinalV3"), vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRefARectrV3"), vec.qvecRe()[RefAInd + 1], vec.qvecIm()[RefAInd + 1], vec.cent()); histosQA.fill(HIST("histQvecRefATwistV3"), vec.qvecRe()[RefAInd + 2], vec.qvecIm()[RefAInd + 2], vec.cent()); @@ -388,9 +435,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[RefBId] > 1e-8) { histosQA.fill(HIST("histQvecRefBUncorV3"), vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], vec.cent()); histosQA.fill(HIST("histEvtPlRefBUncorV3"), helperEP.GetEventPlane(vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefBOccUncorV3"), vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecRefBFinalV3"), vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlRefBFinalV3"), helperEP.GetEventPlane(vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefBOccFinalV3"), vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRefBRectrV3"), vec.qvecRe()[RefBInd + 1], vec.qvecIm()[RefBInd + 1], vec.cent()); histosQA.fill(HIST("histQvecRefBTwistV3"), vec.qvecRe()[RefBInd + 2], vec.qvecIm()[RefBInd + 2], vec.cent()); @@ -413,9 +466,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[DetId] > 1e-8) { histosQA.fill(HIST("histQvecUncorV4"), vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], vec.cent()); histosQA.fill(HIST("histEvtPlUncorV4"), helperEP.GetEventPlane(vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecOccUncorV4"), vec.qvecRe()[DetInd], vec.qvecIm()[DetInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecFinalV4"), vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlFinalV4"), helperEP.GetEventPlane(vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecOccFinalV4"), vec.qvecRe()[DetInd + 3], vec.qvecIm()[DetInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRectrV4"), vec.qvecRe()[DetInd + 1], vec.qvecIm()[DetInd + 1], vec.cent()); histosQA.fill(HIST("histQvecTwistV4"), vec.qvecRe()[DetInd + 2], vec.qvecIm()[DetInd + 2], vec.cent()); @@ -428,9 +487,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[RefAId] > 1e-8) { histosQA.fill(HIST("histQvecRefAUncorV4"), vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], vec.cent()); histosQA.fill(HIST("histEvtPlRefAUncorV4"), helperEP.GetEventPlane(vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefAOccUncorV4"), vec.qvecRe()[RefAInd], vec.qvecIm()[RefAInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecRefAFinalV4"), vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlRefAFinalV4"), helperEP.GetEventPlane(vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefAOccFinalV4"), vec.qvecRe()[RefAInd + 3], vec.qvecIm()[RefAInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRefARectrV4"), vec.qvecRe()[RefAInd + 1], vec.qvecIm()[RefAInd + 1], vec.cent()); histosQA.fill(HIST("histQvecRefATwistV4"), vec.qvecRe()[RefAInd + 2], vec.qvecIm()[RefAInd + 2], vec.cent()); @@ -443,9 +508,15 @@ struct qVectorsCorrection { if (vec.qvecAmp()[RefBId] > 1e-8) { histosQA.fill(HIST("histQvecRefBUncorV4"), vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], vec.cent()); histosQA.fill(HIST("histEvtPlRefBUncorV4"), helperEP.GetEventPlane(vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefBOccUncorV4"), vec.qvecRe()[RefBInd], vec.qvecIm()[RefBInd], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAFinal) { histosQA.fill(HIST("histQvecRefBFinalV4"), vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], vec.cent()); histosQA.fill(HIST("histEvtPlRefBFinalV4"), helperEP.GetEventPlane(vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], nmode), vec.cent()); + if (cfgQAOccupancyStudy) { + histosQA.fill(HIST("histQvecRefBOccFinalV4"), vec.qvecRe()[RefBInd + 3], vec.qvecIm()[RefBInd + 3], vec.cent(), vec.trackOccupancyInTimeRange()); + } if (cfgQAAll) { histosQA.fill(HIST("histQvecRefBRectrV4"), vec.qvecRe()[RefBInd + 1], vec.qvecIm()[RefBInd + 1], vec.cent()); histosQA.fill(HIST("histQvecRefBTwistV4"), vec.qvecRe()[RefBInd + 2], vec.qvecIm()[RefBInd + 2], vec.cent()); @@ -480,7 +551,7 @@ struct qVectorsCorrection { for (uint i = 0; i < cfgnMods->size(); i++) { fillHistosQvec(qVec, cfgnMods->at(i)); - if (cfgQAFinal) { + if (cfgQAFinal && cfgQAFlowStudy) { fillHistosFlow(qVec, tracks, cfgnMods->at(i)); } } diff --git a/DPG/Tasks/AOTTrack/PID/HMPID/CMakeLists.txt b/DPG/Tasks/AOTTrack/PID/HMPID/CMakeLists.txt index 9d153069976..763c9105528 100644 --- a/DPG/Tasks/AOTTrack/PID/HMPID/CMakeLists.txt +++ b/DPG/Tasks/AOTTrack/PID/HMPID/CMakeLists.txt @@ -14,3 +14,8 @@ o2physics_add_dpl_workflow(pid-hmpid-qa SOURCES qaHMPID.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(pid-hmpid + SOURCES analysisHMPID.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/DPG/Tasks/AOTTrack/PID/HMPID/analysisHMPID.cxx b/DPG/Tasks/AOTTrack/PID/HMPID/analysisHMPID.cxx new file mode 100644 index 00000000000..00423aff287 --- /dev/null +++ b/DPG/Tasks/AOTTrack/PID/HMPID/analysisHMPID.cxx @@ -0,0 +1,131 @@ +// 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. + +// O2 includes +#include "ReconstructionDataFormats/Track.h" +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "ReconstructionDataFormats/TrackParametrization.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/TableProducer/PID/pidTOFBase.h" +#include "ReconstructionDataFormats/PID.h" +#include "Common/Core/trackUtilities.h" +#include "ReconstructionDataFormats/DCA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/ASoA.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace o2::aod +{ + +namespace variables_table // declaration of columns to create +{ +DECLARE_SOA_COLUMN(ChAngle, chAngle, float); +DECLARE_SOA_COLUMN(Phi, phi, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(MomentumHMPID, momentumHMPID, float); +DECLARE_SOA_COLUMN(MomentumTrack, momentumTrack, float); +DECLARE_SOA_COLUMN(Xtrack, xtrack, float); +DECLARE_SOA_COLUMN(Ytrack, ytrack, float); +DECLARE_SOA_COLUMN(Xmip, xmip, float); +DECLARE_SOA_COLUMN(Ymip, ymip, float); +DECLARE_SOA_COLUMN(Nphotons, nphotons, float); +DECLARE_SOA_COLUMN(ChargeMIP, chargeMIP, float); +DECLARE_SOA_COLUMN(ClusterSize, clustersize, float); +DECLARE_SOA_COLUMN(Chamber, chamber, float); +DECLARE_SOA_COLUMN(Photons_charge, photons_charge, float); + +DECLARE_SOA_COLUMN(EtaTrack, etatrack, float); +DECLARE_SOA_COLUMN(PhiTrack, phitrack, float); + +DECLARE_SOA_COLUMN(ITSNcluster, itsNcluster, float); +DECLARE_SOA_COLUMN(TPCNcluster, tpcNcluster, float); +DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, float); +DECLARE_SOA_COLUMN(TPCchi2, tpcChi2, float); +DECLARE_SOA_COLUMN(ITSchi2, itsChi2, float); + +DECLARE_SOA_COLUMN(DCAxy, dcaxy, float); +DECLARE_SOA_COLUMN(DCAz, dcaz, float); + +DECLARE_SOA_COLUMN(TPCNSigmaPi, tpcNsigmaPi, float); +DECLARE_SOA_COLUMN(TOFNSigmaPi, tofNsigmaPi, float); +DECLARE_SOA_COLUMN(TPCNSigmaKa, tpcNsigmaKa, float); +DECLARE_SOA_COLUMN(TOFNSigmaKa, tofNsigmaKa, float); +DECLARE_SOA_COLUMN(TPCNSigmaPr, tpcNsigmaPr, float); +DECLARE_SOA_COLUMN(TOFNSigmaPr, tofNsigmaPr, float); +DECLARE_SOA_COLUMN(TPCNSigmaDe, tpcNsigmaDe, float); +DECLARE_SOA_COLUMN(TOFNSigmaDe, tofNsigmaDe, float); + +} // namespace variables_table + +DECLARE_SOA_TABLE(HMPID_analysis, "AOD", "HMPIDANALYSIS", + variables_table::ChAngle, variables_table::Phi, variables_table::Eta, variables_table::MomentumHMPID, + variables_table::MomentumTrack, variables_table::Xtrack, variables_table::Ytrack, variables_table::Xmip, + variables_table::Ymip, variables_table::Nphotons, variables_table::ChargeMIP, variables_table::ClusterSize, + variables_table::Chamber, variables_table::Photons_charge, variables_table::EtaTrack, variables_table::PhiTrack, + variables_table::ITSNcluster, variables_table::TPCNcluster, variables_table::TPCNClsCrossedRows, + variables_table::TPCchi2, variables_table::ITSchi2, variables_table::DCAxy, variables_table::DCAz, + variables_table::TPCNSigmaPi, variables_table::TOFNSigmaPi, variables_table::TPCNSigmaKa, variables_table::TOFNSigmaKa, + variables_table::TPCNSigmaPr, variables_table::TOFNSigmaPr, variables_table::TPCNSigmaDe, variables_table::TOFNSigmaDe); +} // namespace o2::aod + +struct pidHmpidAnalysis { + + Produces HMPID_analysis; + + // using TrackCandidates = soa::Join; + + using CollisionCandidates = o2::soa::Join; + + using TrackCandidates = soa::Join; + + void process(const aod::HMPIDs& hmpids, + TrackCandidates const&, + CollisionCandidates const&) + { + + for (const auto& t : hmpids) { + if (t.track_as().isGlobalTrack() != (uint8_t) true) { + continue; + } + + const auto& track = t.track_as(); + + if (!track.hasITS() || !track.hasTPC() || !track.hasTOF()) { + continue; + } + + /////FILL TABLE + HMPID_analysis(t.hmpidSignal(), t.track_as().phi(), t.track_as().eta(), t.hmpidMom(), + track.p(), t.hmpidXTrack(), t.hmpidYTrack(), t.hmpidXMip(), + t.hmpidYMip(), t.hmpidNPhotons(), t.hmpidQMip(), (t.hmpidClusSize() % 1000000) / 1000, t.hmpidClusSize() / 1000000, + *t.hmpidPhotsCharge(), track.eta(), track.phi(), track.itsNCls(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), + track.tpcChi2NCl(), track.itsChi2NCl(), track.dcaXY(), track.dcaZ(), + track.tpcNSigmaPi(), track.tofNSigmaPi(), track.tpcNSigmaKa(), track.tofNSigmaKa(), + track.tpcNSigmaPr(), track.tofNSigmaPr(), track.tpcNSigmaDe(), track.tofNSigmaDe()); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfg) { return WorkflowSpec{adaptAnalysisTask(cfg)}; } diff --git a/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx b/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx index 27df487189b..fe928c0ddc3 100644 --- a/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx +++ b/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx @@ -48,6 +48,8 @@ struct tofPidBetaQa { ConfigurableAxis tofBetaBins{"tofBetaBins", {4000, 0, 2.f}, "Binning in the TOF beta plot"}; ConfigurableAxis trackLengthBins{"trackLengthBins", {100, 0, 1000.f}, "Binning in track length plot"}; Configurable requireGoodMatchTracks{"requireGoodMatchTracks", false, "Require good match tracks"}; + Configurable mMaxTOFChi2{"maxTOFChi2", 3.f, "Maximum TOF Chi2"}; + Configurable mEtaWindow{"etaWindow", 0.8f, "Window in eta for tracks"}; void init(o2::framework::InitContext&) { @@ -193,7 +195,7 @@ struct tofPidBetaQa { h->GetXaxis()->SetBinLabel(1, "Tracks read"); h->GetXaxis()->SetBinLabel(2, "hasTOF"); h->GetXaxis()->SetBinLabel(3, "isGlobalTrack"); - h->GetXaxis()->SetBinLabel(4, "goodTOFMatch"); + h->GetXaxis()->SetBinLabel(4, TString::Format("TOF chi2 < %.2f", mMaxTOFChi2.value)); } Filter eventFilter = (applyEvSel.node() == 0) || @@ -205,6 +207,7 @@ struct tofPidBetaQa { ((trackSelection.node() == 3) && requireGlobalTrackWoDCAInFilter()) || ((trackSelection.node() == 4) && requireQualityTracksInFilter()) || ((trackSelection.node() == 5) && requireInAcceptanceTracksInFilter()); + Filter etaFilter = (nabs(o2::aod::track::eta) < mEtaWindow); using CollisionCandidate = soa::Filtered>::iterator; using TrackCandidates = soa::Join mMaxTOFChi2) { // Skipping tracks with large Chi2 continue; } histos.fill(HIST("event/trackselection"), 4.f); diff --git a/DPG/Tasks/AOTTrack/qaEfficiency.cxx b/DPG/Tasks/AOTTrack/qaEfficiency.cxx index ca4b78ac20f..0e1c023fc6e 100644 --- a/DPG/Tasks/AOTTrack/qaEfficiency.cxx +++ b/DPG/Tasks/AOTTrack/qaEfficiency.cxx @@ -1050,15 +1050,8 @@ struct QaEfficiency { } if (doPtRadius) { hPtRadiusItsTpc[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusItsTpcPrm[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusItsTpcStr[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusItsTpcTer[histogramIndex]->Fill(mcParticle.pt(), radius); - if (passedTOF) { hPtRadiusItsTpcTof[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusItsTpcTofPrm[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusItsTpcTofStr[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusItsTpcTofTer[histogramIndex]->Fill(mcParticle.pt(), radius); } } } @@ -1098,6 +1091,12 @@ struct QaEfficiency { hEtaItsTpcTofPrm[histogramIndex]->Fill(mcParticle.eta()); hPhiItsTpcTofPrm[histogramIndex]->Fill(mcParticle.phi()); } + if (doPtRadius) { + hPtRadiusItsTpcPrm[histogramIndex]->Fill(mcParticle.pt(), radius); + if (passedTOF) { + hPtRadiusItsTpcTofPrm[histogramIndex]->Fill(mcParticle.pt(), radius); + } + } } } else if (mcParticle.getProcess() == 4) { // Particle decay // Checking mothers @@ -1123,6 +1122,12 @@ struct QaEfficiency { if (passedTOF) { hPtItsTpcTofStr[histogramIndex]->Fill(mcParticle.pt()); } + if (doPtRadius) { + hPtRadiusItsTpcStr[histogramIndex]->Fill(mcParticle.pt(), radius); + if (passedTOF) { + hPtRadiusItsTpcTofStr[histogramIndex]->Fill(mcParticle.pt(), radius); + } + } } if (isFinal(mcParticle)) { if (passedITS && passedTPC && motherIsAccepted) { @@ -1131,6 +1136,12 @@ struct QaEfficiency { if (passedTOF) { hPtItsTpcTofTer[histogramIndex]->Fill(mcParticle.pt()); } + if (doPtRadius) { + hPtRadiusItsTpcTer[histogramIndex]->Fill(mcParticle.pt(), radius); + if (passedTOF) { + hPtRadiusItsTpcTofTer[histogramIndex]->Fill(mcParticle.pt(), radius); + } + } } } } else { // Material @@ -1184,6 +1195,9 @@ struct QaEfficiency { hPtGeneratedPrm[histogramIndex]->Fill(mcParticle.pt()); hEtaGeneratedPrm[histogramIndex]->Fill(mcParticle.eta()); hPhiGeneratedPrm[histogramIndex]->Fill(mcParticle.phi()); + if (doPtRadius) { + hPtRadiusGeneratedPrm[histogramIndex]->Fill(mcParticle.pt(), radius); + } } else { if (mcParticle.getProcess() == 4) { // Particle decay // Checking mothers @@ -1205,8 +1219,14 @@ struct QaEfficiency { } if (motherIsAccepted) { hPtGeneratedStr[histogramIndex]->Fill(mcParticle.pt()); + if (doPtRadius) { + hPtRadiusGeneratedStr[histogramIndex]->Fill(mcParticle.pt(), radius); + } if (isFinal(mcParticle)) { hPtGeneratedTer[histogramIndex]->Fill(mcParticle.pt()); + if (doPtRadius) { + hPtRadiusGeneratedTer[histogramIndex]->Fill(mcParticle.pt(), radius); + } } } } else { // Material @@ -1221,9 +1241,6 @@ struct QaEfficiency { } if (doPtRadius) { hPtRadiusGenerated[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusGeneratedPrm[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusGeneratedStr[histogramIndex]->Fill(mcParticle.pt(), radius); - hPtRadiusGeneratedTer[histogramIndex]->Fill(mcParticle.pt(), radius); } } diff --git a/DPG/Tasks/AOTTrack/qaEventTrack.cxx b/DPG/Tasks/AOTTrack/qaEventTrack.cxx index afab3403224..bfd106f4b8b 100644 --- a/DPG/Tasks/AOTTrack/qaEventTrack.cxx +++ b/DPG/Tasks/AOTTrack/qaEventTrack.cxx @@ -93,6 +93,13 @@ struct qaEventTrack { // options to check the track variables only for PV contributors Configurable checkOnlyPVContributor{"checkOnlyPVContributor", false, "check the track variables only for primary vertex contributors"}; + // options to force or not the presence of TRD (debug) + struct : ConfigurableGroup { + Configurable activateChecksTRD{"activateChecksTRD", false, "Activate the checks wityh TRD - force the track to have or not have TRD"}; + Configurable forceTRD{"forceTRD", false, "Force the track to have TRD"}; + Configurable forceNotTRD{"forceNotTRD", false, "Force the track not to have TRD"}; + } checksTRD; + // configurable binning of histograms ConfigurableAxis binsPt{"binsPt", {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, 2.0, 5.0, 10.0, 20.0, 50.0}, ""}; ConfigurableAxis binsInvPt{"binsInvPt", {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, 2.0, 5.0, 10.0, 20.0, 50.0}, ""}; @@ -152,6 +159,13 @@ struct qaEventTrack { return; } + if (checksTRD.activateChecksTRD) { + std::array casesTRD = {checksTRD.forceTRD, checksTRD.forceNotTRD}; + if (std::accumulate(casesTRD.begin(), casesTRD.end(), 0) != 1) { + LOGP(fatal, "One and only one case between forceTRD and forceNotTRD can be true at a time. Fix it!"); + } + } + // // Next section setups overwrite of configurableAxis if overwriteAxisRangeForPbPb is used. // @@ -1498,6 +1512,17 @@ void qaEventTrack::fillRecoHistogramsGroupedTracks(const C& collision, const T& if (!isSelectedTrack(track)) { continue; } + // TRD checks (debug) + if (checksTRD.activateChecksTRD) { + if (checksTRD.forceTRD && !track.hasTRD()) { + /// We want only tracks that match TRD, but the current one does not match it. Let's skip it. + continue; + } + if (checksTRD.forceNotTRD && track.hasTRD()) { + /// We want only tracks that do not match TRD, but the current one matches it. Let's skip it. + continue; + } + } // fill kinematic variables histos.fill(HIST("Tracks/Kine/pt"), track.pt()); if (track.sign() > 0) { diff --git a/DPG/Tasks/AOTTrack/qaTrackSplitting.cxx b/DPG/Tasks/AOTTrack/qaTrackSplitting.cxx index ca73e9006fd..3125f1e7c03 100644 --- a/DPG/Tasks/AOTTrack/qaTrackSplitting.cxx +++ b/DPG/Tasks/AOTTrack/qaTrackSplitting.cxx @@ -22,7 +22,9 @@ #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/TrackSelectionTables.h" +using namespace o2; using namespace o2::framework; +using namespace o2::framework::expressions; struct qaTrackSplitting { Configurable pdg{"pdg", 2212, "PDG code of the particle to be analysed"}; @@ -40,6 +42,14 @@ struct qaTrackSplitting { Configurable maxDcaXY{"maxDcaXY", 10000.f, "Additional cut on the maximum abs value of the DCA xy"}; Configurable maxDcaZ{"maxDcaZ", 2.f, "Additional cut on the maximum abs value of the DCA z"}; Configurable minTPCNClsFound{"minTPCNClsFound", 0.f, "Additional cut on the minimum value of the number of found clusters in the TPC"}; + + Configurable windowEta{"windowEta", 0.f, "Position in eta of the window"}; + Configurable windowEtaWidth{"windowEtaWidth", 0.1f, "Width of the eta window"}; + Configurable windowPhi{"windowPhi", 0.785f, "Position in phi of the window"}; + Configurable windowPhiWidth{"windowPhiWidth", 0.1f, "Width of the phi window"}; + Configurable windowPt{"windowPt", 1.f, "Position in pt of the window"}; + Configurable windowPtWidth{"windowPtWidth", 0.1f, "Width of the pt window"}; + } cfgCustomTrackCuts; // Histograms @@ -51,6 +61,7 @@ struct qaTrackSplitting { histos.add("tracks", "tracsk", kTH1D, {{10, -0.5, 9.5, "Track selection"}}); histos.add("numberOfRecoed", "recoed", kTH1D, {{10, -0.5, 9.5, "Number of tracks associated to a particle"}}); histos.add("map", "map", kTH3D, {{100, -1, 1, "#Delta #eta"}, {100, -1, 1, "#Delta #varphi"}, {100, -1, 1, "#Delta #it{p}_{T}"}}); + histos.add("deltaPt", "deltaPt", kTH2D, {{100, 0, 5, "#it{p}_{T}"}, {100, -1, 1, "#Delta #it{p}_{T}"}}); histos.add("mapMC", "mapMC", kTH3D, {{100, -1, 1, "#Delta #eta"}, {100, -1, 1, "#Delta #varphi"}, {100, -1, 1, "#Delta #it{p}_{T}"}}); customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(cfgCustomTrackCuts.itsPattern); @@ -69,16 +80,46 @@ struct qaTrackSplitting { customTrackCuts.print(); } - // Global process - using TrackCandidates = o2::soa::Join; - void process(o2::soa::Join::iterator const& collision, - TrackCandidates const& tracks, - o2::aod::McParticles const&) + using CollisionCandidates = o2::soa::Join; + using TrackCandidates = o2::soa::Join; + Filter trackFilterEta = nabs(aod::track::eta - cfgCustomTrackCuts.windowEta) < cfgCustomTrackCuts.windowEtaWidth; + Filter trackFilterPhi = nabs(aod::track::phi - cfgCustomTrackCuts.windowPhi) < cfgCustomTrackCuts.windowPhiWidth; + Filter trackFilterITS = (aod::track::itsClusterSizes > (uint32_t)0); + Filter trackFilterTPC = (aod::track::tpcNClsFindable > (uint8_t)0); + // Filter trackFilterType = (aod::track::TrackType == aod::track::Track); + // Filter filterPt = nabs(aod::track::pt - cfgCustomTrackCuts.windowPt) < cfgCustomTrackCuts.windowPtWidth; + void processData(CollisionCandidates const& collisions, + soa::Filtered const& filteredTracks) + { + for (const auto& coll1 : collisions) { + for (const auto& coll2 : collisions) { + if (coll1.globalIndex() == coll2.globalIndex()) { + continue; + } + for (const auto& track2 : filteredTracks) { + // Compute the delta in pT + for (const auto& track1 : filteredTracks) { + if (track1.globalIndex() == track2.globalIndex()) { + continue; + } + histos.fill(HIST("deltaPt"), track1.pt(), track1.pt() - track2.pt()); + } + } + } + } + } + PROCESS_SWITCH(qaTrackSplitting, processData, "Process Data", true); + + using CollisionCandidatesMC = soa::Join; + using TrackCandidatesMC = o2::soa::Join; + void processMC(CollisionCandidatesMC::iterator const& collision, + TrackCandidatesMC const& tracks, + o2::aod::McParticles const&) { if (!collision.sel8()) { return; } - typedef std::shared_ptr trkType; + typedef std::shared_ptr trkType; std::map> particleUsageCounter; for (auto track : tracks) { @@ -87,11 +128,12 @@ struct qaTrackSplitting { continue; } histos.fill(HIST("tracks"), 1); - if (track.mcParticle().pdgCode() != pdg) { + const auto& mcParticle = track.mcParticle(); + if (mcParticle.pdgCode() != pdg) { continue; } histos.fill(HIST("tracks"), 2); - if (!track.mcParticle().isPhysicalPrimary()) { + if (!mcParticle.isPhysicalPrimary()) { continue; } histos.fill(HIST("tracks"), 3); @@ -101,21 +143,28 @@ struct qaTrackSplitting { histos.fill(HIST("tracks"), 4); particleUsageCounter[track.mcParticleId()].push_back(std::make_shared(track)); } - for (const auto& [mcId, tracks] : particleUsageCounter) { - histos.fill(HIST("numberOfRecoed"), tracks.size()); - if (tracks.size() > 1) { + for (const auto& [mcId, tracksMatched] : particleUsageCounter) { + histos.fill(HIST("numberOfRecoed"), tracksMatched.size()); + if (tracksMatched.size() > 1) { bool isFirst = true; - for (const auto& track : tracks) { + for (const auto& track : tracksMatched) { if (isFirst) { isFirst = false; - histos.fill(HIST("mapMC"), track->eta() - track->mcParticle().eta(), track->phi() - track->mcParticle().phi(), track->pt() - track->mcParticle().pt()); + histos.fill(HIST("mapMC"), + track->eta() - track->mcParticle().eta(), + track->phi() - track->mcParticle().phi(), + track->pt() - track->mcParticle().pt()); continue; } - histos.fill(HIST("map"), track->eta() - tracks[0]->eta(), track->phi() - tracks[0]->phi(), track->pt() - tracks[0]->pt()); + histos.fill(HIST("map"), + track->eta() - tracksMatched[0]->eta(), + track->phi() - tracksMatched[0]->phi(), + track->pt() - tracksMatched[0]->pt()); } } } } + PROCESS_SWITCH(qaTrackSplitting, processMC, "Process MC", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGCF/Femto3D/Core/femto3dPairTask.h b/PWGCF/Femto3D/Core/femto3dPairTask.h index 8480cbcbadd..e531c25ac5a 100755 --- a/PWGCF/Femto3D/Core/femto3dPairTask.h +++ b/PWGCF/Femto3D/Core/femto3dPairTask.h @@ -109,14 +109,14 @@ float GetKstarFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& secon { if (isIdentical) { TLorentzVector fourmomentadiff = first4momentum - second4momentum; - return 0.5 * abs(fourmomentadiff.Mag()); + return 0.5 * std::fabs(fourmomentadiff.Mag()); } else { TLorentzVector fourmomentasum = first4momentum + second4momentum; TLorentzVector fourmomentadif = first4momentum - second4momentum; fourmomentadif.Boost((-1) * fourmomentasum.BoostVector()); - return 0.5 * abs(fourmomentadif.Vect().Mag()); + return 0.5 * std::fabs(fourmomentadif.Vect().Mag()); } } @@ -252,9 +252,9 @@ bool FemtoPair::IsClosePair(const float& deta, const float& dphi, con return true; if (_magfield1 * _magfield2 == 0) return true; - if (std::pow(abs(GetEtaDiff()) / deta, 2) + std::pow(abs(GetPhiStarDiff(radius)) / dphi, 2) < 1.0f) + if (std::pow(std::fabs(GetEtaDiff()) / deta, 2) + std::pow(std::fabs(GetPhiStarDiff(radius)) / dphi, 2) < 1.0f) return true; - // if (abs(GetEtaDiff()) < deta && abs(GetPhiStarDiff(radius)) < dphi) + // if (std::fabs(GetEtaDiff()) < deta && std::fabs(GetPhiStarDiff(radius)) < dphi) // return true; return false; diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx index 8172d07bbf0..5b108aef576 100644 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -492,7 +492,7 @@ struct singleTrackSelector { return; } - if (abs(mcCollision.posZ()) > _vertexZ) { + if (std::fabs(mcCollision.posZ()) > _vertexZ) { return; } diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx index e3f5fa8f0c3..e39a9449040 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -380,7 +380,7 @@ struct FemtoCorrelations { LOGF(fatal, "One of passed PDG is 0!!!"); for (auto track : tracks) { - if (abs(track.template singleCollSel_as>().posZ()) > _vertexZ) + if (std::fabs(track.template singleCollSel_as>().posZ()) > _vertexZ) continue; if (_removeSameBunchPileup && !track.template singleCollSel_as>().isNoSameBunchPileup()) continue; @@ -400,7 +400,7 @@ struct FemtoCorrelations { continue; if (track.template singleCollSel_as>().occupancy() < _OccupancyCut.value.first || track.template singleCollSel_as>().occupancy() >= _OccupancyCut.value.second) continue; - if (abs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || abs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) + if (std::fabs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || std::fabs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) continue; if (track.sign() == _sign_1 && (track.p() < _PIDtrshld_1 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_1) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_1, _tpcNSigmaResidual_1.value))) { // filling the map: eventID <-> selected particles1 diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx index c9da488f56d..4c095f134df 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -321,7 +321,7 @@ struct FemtoCorrelationsMC { int trackPDG, trackOrigin; for (auto track : tracks) { - if (abs(track.template singleCollSel_as>().posZ()) > _vertexZ) + if (std::fabs(track.template singleCollSel_as>().posZ()) > _vertexZ) continue; if (track.tpcFractionSharedCls() > _tpcFractionSharedCls || track.itsNCls() < _itsNCls) continue; @@ -351,7 +351,7 @@ struct FemtoCorrelationsMC { if (trackOrigin > -1 && trackOrigin < 3) DCA_histos_1[centBin][track.origin()]->Fill(track.pt(), track.dcaXY(), track.dcaZ()); - if (abs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || abs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) + if (std::fabs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || std::fabs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) continue; trackPDG = abs(track.pdgCode()); @@ -372,7 +372,7 @@ struct FemtoCorrelationsMC { if (trackOrigin > -1 && trackOrigin < 3) DCA_histos_2[centBin][track.origin()]->Fill(track.pt(), track.dcaXY(), track.dcaZ()); - if (abs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || abs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) + if (std::fabs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || std::fabs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) continue; trackPDG = abs(track.pdgCode()); diff --git a/PWGCF/Femto3D/Tasks/femto3dQA.cxx b/PWGCF/Femto3D/Tasks/femto3dQA.cxx index ba04c6c61a0..e544b1bdacb 100644 --- a/PWGCF/Femto3D/Tasks/femto3dQA.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dQA.cxx @@ -186,7 +186,7 @@ struct QAHistograms { if (_requestNoCollInTimeRangeStandard && !track.template singleCollSel_as().noCollInTimeRangeStandard()) continue; - if (abs(track.template singleCollSel_as().posZ()) > _vertexZ) + if (std::fabs(track.template singleCollSel_as().posZ()) > _vertexZ) continue; if (track.template singleCollSel_as().multPerc() < _centCut.value.first || track.template singleCollSel_as().multPerc() >= _centCut.value.second) continue; @@ -196,7 +196,7 @@ struct QAHistograms { continue; if ((track.tpcFractionSharedCls()) > _tpcFractionSharedCls || (track.itsNCls()) < _itsNCls) continue; - if (abs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || abs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) + if (std::fabs(track.dcaXY()) > _dcaXY.value[0] + _dcaXY.value[1] * std::pow(track.pt(), _dcaXY.value[2]) || std::fabs(track.dcaZ()) > _dcaZ.value[0] + _dcaZ.value[1] * std::pow(track.pt(), _dcaZ.value[2])) continue; if constexpr (FillExtra) { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h index 6d48650c2ba..c08c131ab99 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h @@ -74,7 +74,6 @@ class FemtoUniverse3DContainer /// \param mTAxis axis object for the mT axis /// \param use3dplots Flag to fill 3D plots /// \param isiden Identical or non-identical particle pair - /// \param islcms LCMS or PRF template void init_base(std::string folderName, std::string femtoObs1D, std::string femtoObsKout, std::string femtoObsKside, std::string femtoObsKlong, T femtoObsAxis1D, T femtoObsAxisOut, T femtoObsAxisSide, T femtoObsAxisLong, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, bool use3dplots, bool isiden) { @@ -214,13 +213,13 @@ class FemtoUniverse3DContainer /// \param isiden Choosing identical or non-identical pairs /// \param islcm Choosing LCMS or PRF template - void setPair(T const& part1, T const& part2, const int mult, bool use3dplots, bool isiden, bool islcms) + void setPair(T const& part1, T const& part2, const int mult, bool use3dplots, bool isiden) { std::vector f3d; const float kT = FemtoUniverseMath::getkT(part1, mMassOne, part2, mMassTwo); const float mT = FemtoUniverseMath::getmT(part1, mMassOne, part2, mMassTwo); - f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo, isiden, islcms); + f3d = FemtoUniverseMath::newpairfunc(part1, mMassOne, part2, mMassTwo, isiden); const float femtoObs1D = f3d[0]; const float femtoObsKout = f3d[1]; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h index cd992906c89..95c0165b26d 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h @@ -149,9 +149,8 @@ class FemtoUniverseMath /// \param part2 Particle 2 /// \param mass2 Mass of particle 2 /// \param isiden Identical or non-identical particle pair - /// \param islcms LCMS or PRF template - static std::vector getpairmom3d(const T& part1, const float mass1, const T& part2, const float mass2, bool isiden, bool islcms) + static std::vector newpairfunc(const T& part1, const float mass1, const T& part2, const float mass2, bool isiden) { const double E1 = sqrt(pow(part1.px(), 2) + pow(part1.py(), 2) + pow(part1.pz(), 2) + pow(mass1, 2)); const double E2 = sqrt(pow(part2.px(), 2) + pow(part2.py(), 2) + pow(part2.pz(), 2) + pow(mass2, 2)); @@ -165,80 +164,62 @@ class FemtoUniverseMath const double tPx = trackSum.px(); const double tPy = trackSum.py(); const double tPz = trackSum.pz(); - const double tPE = trackSum.E(); + const double tE = trackSum.E(); - const double tPt = trackSum.pt(); - const double tMt = trackSum.mt(); - const double tPinv = std::sqrt((tMt * tMt) - (tPt * tPt)); + double tPt = (tPx * tPx + tPy * tPy); + double tMt = (tE * tE - tPz * tPz); + double tM = sqrt(tMt - tPt); + tMt = sqrt(tMt); + tPt = sqrt(tPt); - float nullmass = 0.0; - const double m1 = std::max(nullmass, mass1); - const double m2 = std::max(nullmass, mass2); - - const double tQinvL = std::pow((E1 - E2), 2) - std::pow((part1.px() - part2.px()), 2) - - std::pow((part1.py() - part2.py()), 2) - std::pow((part1.pz() - part2.pz()), 2); - - double tQ = (m1 - m2) / tPinv; - tQ = ::sqrt(tQ * tQ - tQinvL); - - const double fKStarCalc = tQ / 2.0; - vect.push_back(fKStarCalc); + double fDKOutLCMS, fDKSideLCMS, fDKLongLCMS; + double fDKOut, fDKSide, fDKLong, fDE; + double px1LCMS, py1LCMS, pz1LCMS; + double px2LCMS, py2LCMS, pz2LCMS; + double kstar; // Boost to LCMS - const double beta = tPz / tPE; - const double gamma = tPE / tMt; + const double beta = tPz / tE; + const double gamma = tE / tMt; - const double px1L = (part1.px() * tPx + part1.py() * tPy) / tPt; - const double py1L = (-part1.px() * tPy + part1.py() * tPx) / tPt; - const double pz1L = gamma * (part1.pz() - beta * E1); - const double pE1L = gamma * (E1 - beta * part1.pz()); + fDKOut = (part1.px() * tPx + part1.py() * tPy) / tPt; + fDKSide = (-part1.px() * tPy + part1.py() * tPx) / tPt; + fDKLong = gamma * (part1.pz() - beta * E1); + fDE = gamma * (E1 - beta * part1.pz()); - const double px2L = (part2.px() * tPx + part2.py() * tPy) / tPt; - const double py2L = (-part2.px() * tPy + part2.py() * tPx) / tPt; - const double pz2L = gamma * (part2.pz() - beta * E2); - const double pE2L = gamma * (E2 - beta * part2.pz()); + px1LCMS = fDKOut; + py1LCMS = fDKSide; + pz1LCMS = fDKLong; + // pE1LCMS = fDE; - double fDKOutLCMS; - double fDKSideLCMS; - double fDKLongLCMS; + px2LCMS = (part2.px() * tPx + part2.py() * tPy) / tPt; + py2LCMS = (part2.py() * tPx - part2.px() * tPy) / tPt; + pz2LCMS = gamma * (part2.pz() - beta * E2); + // pE2LCMS = gamma * (E2 - beta * part2.pz()); - double fDKOutPRF; - double fDKSidePRF; - double fDKLongPRF; - - if (!isiden) { - fDKOutLCMS = px1L; - fDKSideLCMS = py1L; - fDKLongLCMS = pz1L; - } else { - fDKOutLCMS = px1L - px2L; - fDKSideLCMS = py1L - py2L; - fDKLongLCMS = pz1L - pz2L; - } + fDKOutLCMS = px1LCMS - px2LCMS; + fDKSideLCMS = py1LCMS - py2LCMS; + fDKLongLCMS = pz1LCMS - pz2LCMS; // Boost to PRF + const double betaOut = tPt / tMt; - const double gammaOut = tMt / tPinv; + const double gammaOut = tMt / tM; - if (!isiden) { - fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * pE1L); - fDKSidePRF = fDKSideLCMS; - fDKLongPRF = fDKLongLCMS; - } else { - fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * (pE1L - pE2L)); - fDKSidePRF = fDKSideLCMS; - fDKLongPRF = fDKLongLCMS; - } + fDKOut = gammaOut * (fDKOut - betaOut * fDE); + kstar = sqrt(fDKOut * fDKOut + fDKSide * fDKSide + fDKLong * fDKLong); - if (islcms) { + if (isiden) { + vect.push_back(2.0 * (kstar)); vect.push_back(fDKOutLCMS); vect.push_back(fDKSideLCMS); vect.push_back(fDKLongLCMS); } else { - vect.push_back(fDKOutPRF); - vect.push_back(fDKSidePRF); - vect.push_back(fDKLongPRF); + vect.push_back(kstar); + vect.push_back(fDKOut); + vect.push_back(fDKSide); + vect.push_back(fDKLong); } return vect; } diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h index 9d3c60bea79..1be3d76085e 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h @@ -184,24 +184,24 @@ class PairSHCentMultKt /// \param ktval kT value template void fill_mult_NumDen(T const& part1, T const& part2, uint8_t ChosenEventType, - int maxl, int multval, float ktval) + int maxl, int multval, float ktval, bool isiden) { int multbinval; int absmultval = multval; - if ((absmultval > CentMultBins[0]) && (absmultval <= CentMultBins[1])) { + if ((absmultval >= CentMultBins[0]) && (absmultval < CentMultBins[1])) { multbinval = 0; - } else if (absmultval <= CentMultBins[2]) { + } else if (absmultval < CentMultBins[2]) { multbinval = 1; - } else if (absmultval <= CentMultBins[3]) { + } else if (absmultval < CentMultBins[3]) { multbinval = 2; - } else if (ktval <= CentMultBins[4]) { + } else if (ktval < CentMultBins[4]) { multbinval = 3; } else { return; } // std::cout<<"multbinval "< void fill_kT_NumDen(T const& part1, T const& part2, uint8_t ChosenEventType, - int maxl, int multval, float ktval) + int maxl, int multval, float ktval, bool isiden) { int ktbinval = -1; - if ((ktval > KtBins[0]) && (ktval <= KtBins[1])) { + if ((ktval >= KtBins[0]) && (ktval < KtBins[1])) { ktbinval = 0; - } else if (ktval <= KtBins[2]) { + } else if (ktval < KtBins[2]) { ktbinval = 1; - } else if (ktval <= KtBins[3]) { + } else if (ktval < KtBins[3]) { ktbinval = 2; - } else if (ktval <= KtBins[4]) { + } else if (ktval < KtBins[4]) { ktbinval = 3; } else { return; } - AddEventPair(part1, part2, ChosenEventType, maxl, multval, ktbinval); + AddEventPair(part1, part2, ChosenEventType, maxl, multval, ktbinval, isiden); } /// Set the PDG codes of the two particles involved @@ -262,14 +262,14 @@ class PairSHCentMultKt /// \param ktval kT value template void AddEventPair(T const& part1, T const& part2, uint8_t ChosenEventType, - int /*maxl*/, int multval, int ktval) + int /*maxl*/, int multval, int ktval, bool isiden) { int fMultBin = multval; int fKtBin = ktval; std::vector> fYlmBuffer(fMaxJM); std::vector f3d; - f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo, - true, true); + f3d = FemtoUniverseMath::newpairfunc(part1, mMassOne, part2, mMassTwo, + isiden); const float qout = f3d[1]; const float qside = f3d[2]; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h index 0838ce5e5b3..4bc96996408 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h @@ -159,20 +159,17 @@ class FemtoUniverseSHContainer /// \param ChosenEventType same or mixed event /// \param maxl Maximum valie of L component of the spherical harmonics template - void AddEventPair(T const& part1, T const& part2, uint8_t ChosenEventType, int /*maxl*/) + void AddEventPair(T const& part1, T const& part2, uint8_t ChosenEventType, int /*maxl*/, bool isiden) { - // int fMaxL = 2; - // int fMaxJM = (2+1)*(2+1); std::vector> fYlmBuffer(fMaxJM); std::vector f3d; - f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo, true, true); + f3d = FemtoUniverseMath::newpairfunc(part1, mMassOne, part2, mMassTwo, isiden); - // const float qstar = f3d[0]; + const float kv = f3d[0]; const float qout = f3d[1]; const float qside = f3d[2]; const float qlong = f3d[3]; - double kv = sqrt(qout * qout + qside * qside + qlong * qlong); int nqbin = fbinctn->GetXaxis()->FindFixBin(kv) - 1; FemtoUniverseSpherHarMath Ylm; diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 760e76c88bb..0bd9b95b771 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -432,10 +432,10 @@ struct femtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackD0mesonData || doprocessTrackCentRun2Data || doprocessTrackCentRun3Data || doprocessTrackV0CentRun3) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTruthAndFullMC || doprocessFullMCCent) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackD0mesonData || doprocessTrackCentRun2Data || doprocessTrackCentRun3Data || doprocessTrackV0CentRun3) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMC || doprocessFullMCCent) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackD0mesonData || doprocessTrackCentRun2Data || doprocessTrackCentRun3Data || doprocessTrackV0CentRun3) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTruthAndFullMC || doprocessFullMCCent) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackD0mesonData || doprocessTrackCentRun2Data || doprocessTrackCentRun3Data || doprocessTrackV0CentRun3) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMC || doprocessFullMCCent) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); @@ -1395,7 +1395,7 @@ struct femtoUniverseProducerTask { std::vector tmpPDGCodes = ConfMCTruthPDGCodes; // necessary due to some features of the Configurable for (uint32_t pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { - if ((pdgCode == 333) && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles + if ((pdgCode == 333)) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles pass = true; } else { if (particle.isPhysicalPrimary() || (ConfActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) @@ -1680,7 +1680,7 @@ struct femtoUniverseProducerTask { aod::McCollisions const& mccols, aod::McParticles const& mcParticles, soa::Join const& collisions, - soa::Join const& tracks, + soa::Filtered> const& tracks, soa::Join const& fullV0s, aod::BCsWithTimestamps const&) { diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index c9b2eb7bed3..56dc219c883 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -38,6 +38,7 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include #include +#include "CCDB/BasicCCDBManager.h" using namespace o2; using namespace o2::analysis::femtoUniverse; @@ -159,7 +160,8 @@ struct femtoUniversePairTaskTrackPhi { ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; // Efficiency - Configurable ConfLocalEfficiency{"ConfLocalEfficiency", "", "Local path to efficiency .root file"}; + Configurable ConfLocalEfficiencyProton{"ConfLocalEfficiencyProton", "", "Local path to proton efficiency th2d file"}; + Configurable ConfLocalEfficiencyPhi{"ConfLocalEfficiencyPhi", "", "Local path to Phi efficiency th2d file"}; FemtoUniverseAngularContainer sameEventAngularCont; FemtoUniverseAngularContainer mixedEventAngularCont; @@ -175,9 +177,9 @@ struct femtoUniversePairTaskTrackPhi { HistogramRegistry registryMCreco{"MCrecoHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry registryPhiMinvBackground{"registryPhiMinvBackground", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; - std::unique_ptr plocalEffFile; - std::unique_ptr plocalEffp1; - std::unique_ptr plocalEffp2; + Service ccdb; + TH2D* protoneff; + TH2D* phieff; // PID for protons bool IsProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx @@ -423,15 +425,25 @@ struct femtoUniversePairTaskTrackPhi { pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiCutMin.value, ConfCPRdeltaPhiCutMax.value, ConfCPRdeltaEtaCutMin.value, ConfCPRdeltaEtaCutMax.value, ConfCPRChosenRadii.value, ConfCPRPlotPerRadii.value, ConfCPRInvMassCutMin.value, ConfCPRInvMassCutMax.value); } - if (!ConfLocalEfficiency.value.empty()) { - plocalEffFile = std::unique_ptr(TFile::Open(ConfLocalEfficiency.value.c_str(), "read")); - if (!plocalEffFile || plocalEffFile.get()->IsZombie()) { - LOGF(fatal, "Could not load efficiency histogram from %s", ConfLocalEfficiency.value.c_str()); - } + /// Initializing CCDB + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); - plocalEffp1 = (ConfTrack.ConfTrackSign > 0) ? std::unique_ptr(plocalEffFile.get()->Get("PrPlus")) : std::unique_ptr(plocalEffFile.get()->Get("PrMinus")); - plocalEffp2 = std::unique_ptr(plocalEffFile.get()->Get("Phi")); - LOGF(info, "Loaded efficiency histograms for track-Phi."); + if (!ConfLocalEfficiencyProton.value.empty()) { + protoneff = ccdb->getForTimeStamp(ConfLocalEfficiencyProton.value.c_str(), -1); + if (!protoneff || protoneff->IsZombie()) { + LOGF(fatal, "Could not load efficiency protoneff histogram from %s", ConfLocalEfficiencyProton.value.c_str()); + } + } + if (!ConfLocalEfficiencyPhi.value.empty()) { + phieff = ccdb->getForTimeStamp(ConfLocalEfficiencyPhi.value.c_str(), -1); + if (!phieff || phieff->IsZombie()) { + LOGF(fatal, "Could not load efficiency phieff histogram from %s", ConfLocalEfficiencyPhi.value.c_str()); + } } vPIDPhiCandidate = ConfPhi.ConfPIDPhi.value; @@ -549,8 +561,8 @@ struct femtoUniversePairTaskTrackPhi { } float weight = 1.0f; - if (plocalEffp1) { - weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(track.pt(), track.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(phicandidate.pt(), phicandidate.eta())); + if (phieff) { + weight = protoneff->GetBinContent(protoneff->FindBin(track.pt(), track.eta())) * phieff->GetBinContent(phieff->FindBin(phicandidate.pt(), phicandidate.eta())); sameEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); } else { sameEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); @@ -656,8 +668,8 @@ struct femtoUniversePairTaskTrackPhi { } float weight = 1.0f; - if (plocalEffp1) { - weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(track.pt(), track.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(phicandidate.pt(), phicandidate.eta())); + if (protoneff) { + weight = protoneff->GetBinContent(protoneff->FindBin(track.pt(), track.eta())) * phieff->GetBinContent(phieff->FindBin(phicandidate.pt(), phicandidate.eta())); mixedEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); } else { mixedEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); @@ -775,7 +787,7 @@ struct femtoUniversePairTaskTrackPhi { continue; // no MC particle const auto& mcpart = mcparts.iteratorAt(mcPartId); if (part.partType() == aod::femtouniverseparticle::ParticleType::kPhi) { - if ((mcpart.pdgMCTruth() == 333) && (mcpart.partOriginMCTruth() == aod::femtouniverseMCparticle::ParticleOriginMCTruth::kFake)) { + if ((mcpart.pdgMCTruth() == 333) && (mcpart.partOriginMCTruth() == aod::femtouniverseMCparticle::ParticleOriginMCTruth::kPrimary)) { registryMCreco.fill(HIST("MCrecoPhi"), mcpart.pt(), mcpart.eta()); // phi } } else if (part.partType() == aod::femtouniverseparticle::ParticleType::kTrack) { diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx index ed5ff3c56f1..d5b7c010acc 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx @@ -476,9 +476,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); if (!cfgProcessMultBins) { - sameEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + sameEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); sameEventMultCont.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } } @@ -515,16 +515,16 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { if (rand > 0.5) { if (!cfgProcessMultBins) { - sameEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + sameEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); sameEventMultContPP.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } } else { if (!cfgProcessMultBins) { - sameEventContPP.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + sameEventContPP.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - k3d = FemtoUniverseMath::getpairmom3d(p2, mass2, p1, mass1, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::newpairfunc(p2, mass2, p1, mass1, ConfIsIden); sameEventMultContPP.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } } @@ -538,16 +538,16 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { if (rand > 0.5) { if (!cfgProcessMultBins) { - sameEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + sameEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); sameEventMultContMM.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } } else { if (!cfgProcessMultBins) { - sameEventContMM.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + sameEventContMM.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - k3d = FemtoUniverseMath::getpairmom3d(p2, mass2, p1, mass1, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::newpairfunc(p2, mass2, p1, mass1, ConfIsIden); sameEventMultContMM.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } } @@ -650,9 +650,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { case 1: { float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); if (!cfgProcessMultBins) { - mixedEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + mixedEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); mixedEventMultCont.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } break; @@ -660,9 +660,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { case 2: { float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass1); if (!cfgProcessMultBins) { - mixedEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + mixedEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); mixedEventMultContPP.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } break; @@ -671,9 +671,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { case 3: { float kT = FemtoUniverseMath::getkT(p1, mass2, p2, mass2); if (!cfgProcessMultBins) { - mixedEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + mixedEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden); } else { - std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); mixedEventMultContMM.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } break; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index 9d4f278c51e..8dc39769732 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -132,8 +132,9 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// Event part Configurable ConfV0MLow{"ConfV0MLow", 0.0, "Lower limit for V0M multiplicity"}; Configurable ConfV0MHigh{"ConfV0MHigh", 25000.0, "Upper limit for V0M multiplicity"}; - Filter collV0Mfilter = ((o2::aod::femtouniversecollision::multV0M > ConfV0MLow) && (o2::aod::femtouniversecollision::multV0M < ConfV0MHigh)); + using FilteredFDCollisions = soa::Filtered; + using FilteredFDCollision = soa::Filtered::iterator; // Filter trackAdditionalfilter = (nabs(aod::femtouniverseparticle::eta) < twotracksconfigs.ConfEtaMax); // example filtering on configurable /// Particle part @@ -149,7 +150,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { ConfigurableAxis ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; ConfigurableAxis ConfmultBins3D{"ConfmultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; ConfigurableAxis ConfkstarBins{"ConfkstarBins", {60, 0.0, 0.3}, "binning kstar"}; ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; @@ -413,7 +414,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { template void fillCollision(CollisionType col) { - MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); + MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multV0M()})); eventHisto.fillQA(col); } @@ -474,7 +475,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); - sameEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT); + sameEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden); } } else { for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsOne))) { @@ -506,9 +507,9 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { case 2: { rand = randgen->Rndm(); if (rand > 0.5) { - sameEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT); + sameEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden); } else if (rand <= 0.5) { - sameEventMultContPP.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT); + sameEventMultContPP.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden); } break; } @@ -516,9 +517,9 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { case 3: { rand = randgen->Rndm(); if (rand > 0.5) { - sameEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT); + sameEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden); } else if (rand <= 0.5) { - sameEventMultContMM.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT); + sameEventMultContMM.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden); } break; } @@ -533,7 +534,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// process function for to call doSameEvent with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoUniverseParticleTable - void processSameEvent(soa::Filtered::iterator& col, + void processSameEvent(FilteredFDCollision& col, FilteredFemtoFullParticles& parts) { fillCollision(col); @@ -544,15 +545,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { bool fillQA = true; if (cfgProcessPM) { - doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 1, fillQA); + doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multV0M(), 1, fillQA); } if (cfgProcessPP) { - doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multNtr(), 2, fillQA); + doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multV0M(), 2, fillQA); } if (cfgProcessMM) { - doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); + doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multV0M(), 3, fillQA); } } PROCESS_SWITCH(femtoUniversePairTaskTrackTrackSpherHarMultKtExtended, processSameEvent, "Enable processing same event", true); @@ -605,15 +606,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); switch (ContType) { case 1: { - mixedEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT); + mixedEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT, ConfIsIden); break; } case 2: { - mixedEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT); + mixedEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT, ConfIsIden); break; } case 3: { - mixedEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT); + mixedEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT, ConfIsIden); break; } default: @@ -625,12 +626,12 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// process function for to call doMixedEvent with Data /// @param cols subscribe to the collisions table (Data) /// @param parts subscribe to the femtoUniverseParticleTable - void processMixedEvent(soa::Filtered& cols, + void processMixedEvent(FilteredFDCollisions& cols, FilteredFemtoFullParticles& parts) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); + const int multiplicityCol = collision1.multV0M(); MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); const auto& magFieldTesla1 = collision1.magField(); @@ -690,7 +691,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); + const int multiplicityCol = collision1.multV0M(); MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); const auto& magFieldTesla1 = collision1.magField(); diff --git a/PWGCF/Flow/Tasks/FlowTask.cxx b/PWGCF/Flow/Tasks/FlowTask.cxx index 35f227c8c63..2b9cd8e1be7 100644 --- a/PWGCF/Flow/Tasks/FlowTask.cxx +++ b/PWGCF/Flow/Tasks/FlowTask.cxx @@ -68,6 +68,8 @@ struct FlowTask { O2_DEFINE_CONFIGURABLE(cfgMagnetField, std::string, "GLO/Config/GRPMagField", "CCDB path to Magnet field object") O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 500, "High cut on TPC occupancy") O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") + Configurable> cfgUserDefineGFWCorr{"cfgUserDefineGFWCorr", std::vector{"refN02 {2} refP02 {-2}", "refN12 {2} refP12 {-2}"}, "User defined GFW CorrelatorConfig"}; + Configurable> cfgUserDefineGFWName{"cfgUserDefineGFWName", std::vector{"Ch02Gap22", "Ch12Gap22"}, "User defined GFW Name"}; ConfigurableAxis axisVertex{"axisVertex", {40, -20, 20}, "vertex axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; @@ -75,7 +77,7 @@ struct FlowTask { ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; ConfigurableAxis axisPtHist{"axisPtHist", {100, 0., 10.}, "pt axis for histograms"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, "pt axis for histograms"}; - ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "centrality axis for histograms"}; + ConfigurableAxis axisIndependent{"axisIndependent", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "X axis for histograms"}; ConfigurableAxis axisCentForQA{"axisCentForQA", {100, 0, 100}, "centrality for QA"}; ConfigurableAxis axisNch{"axisNch", {4000, 0, 4000}, "N_{ch}"}; ConfigurableAxis axisT0C{"axisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; @@ -185,12 +187,12 @@ struct FlowTask { registry.add("hDCAxy", "DCAxy after cuts; DCAxy (cm); Pt", {HistType::kTH2D, {{50, -1, 1}, {50, 0, 10}}}); registry.add("hTrackCorrection2d", "Correlation table for number of tracks table; uncorrected track; corrected track", {HistType::kTH2D, {axisNch, axisNch}}); // additional Output histograms - registry.add("hMeanPt", "", {HistType::kTProfile, {axisCentrality}}); - registry.add("hMeanPtWithinGap08", "", {HistType::kTProfile, {axisCentrality}}); - registry.add("c22_gap08_Weff", "", {HistType::kTProfile, {axisCentrality}}); - registry.add("c22_gap08_trackMeanPt", "", {HistType::kTProfile, {axisCentrality}}); - registry.add("PtVariance_partA_WithinGap08", "", {HistType::kTProfile, {axisCentrality}}); - registry.add("PtVariance_partB_WithinGap08", "", {HistType::kTProfile, {axisCentrality}}); + registry.add("hMeanPt", "", {HistType::kTProfile, {axisIndependent}}); + registry.add("hMeanPtWithinGap08", "", {HistType::kTProfile, {axisIndependent}}); + registry.add("c22_gap08_Weff", "", {HistType::kTProfile, {axisIndependent}}); + registry.add("c22_gap08_trackMeanPt", "", {HistType::kTProfile, {axisIndependent}}); + registry.add("PtVariance_partA_WithinGap08", "", {HistType::kTProfile, {axisIndependent}}); + registry.add("PtVariance_partB_WithinGap08", "", {HistType::kTProfile, {axisIndependent}}); // initial array BootstrapArray.resize(cfgNbootstrap); @@ -198,11 +200,11 @@ struct FlowTask { BootstrapArray[i].resize(kCount_ExtraProfile); } for (int i = 0; i < cfgNbootstrap; i++) { - BootstrapArray[i][kMeanPt_InGap08] = registry.add(Form("BootstrapContainer_%d/hMeanPtWithinGap08", i), "", {HistType::kTProfile, {axisCentrality}}); - BootstrapArray[i][kC22_Gap08_Weff] = registry.add(Form("BootstrapContainer_%d/c22_gap08_Weff", i), "", {HistType::kTProfile, {axisCentrality}}); - BootstrapArray[i][kC22_Gap08_MeanPt] = registry.add(Form("BootstrapContainer_%d/c22_gap08_trackMeanPt", i), "", {HistType::kTProfile, {axisCentrality}}); - BootstrapArray[i][kPtVarParA_InGap08] = registry.add(Form("BootstrapContainer_%d/PtVariance_partA_WithinGap08", i), "", {HistType::kTProfile, {axisCentrality}}); - BootstrapArray[i][kPtVarParB_InGap08] = registry.add(Form("BootstrapContainer_%d/PtVariance_partB_WithinGap08", i), "", {HistType::kTProfile, {axisCentrality}}); + BootstrapArray[i][kMeanPt_InGap08] = registry.add(Form("BootstrapContainer_%d/hMeanPtWithinGap08", i), "", {HistType::kTProfile, {axisIndependent}}); + BootstrapArray[i][kC22_Gap08_Weff] = registry.add(Form("BootstrapContainer_%d/c22_gap08_Weff", i), "", {HistType::kTProfile, {axisIndependent}}); + BootstrapArray[i][kC22_Gap08_MeanPt] = registry.add(Form("BootstrapContainer_%d/c22_gap08_trackMeanPt", i), "", {HistType::kTProfile, {axisIndependent}}); + BootstrapArray[i][kPtVarParA_InGap08] = registry.add(Form("BootstrapContainer_%d/PtVariance_partA_WithinGap08", i), "", {HistType::kTProfile, {axisIndependent}}); + BootstrapArray[i][kPtVarParB_InGap08] = registry.add(Form("BootstrapContainer_%d/PtVariance_partB_WithinGap08", i), "", {HistType::kTProfile, {axisIndependent}}); } o2::framework::AxisSpec axis = axisPt; @@ -250,13 +252,24 @@ struct FlowTask { oba->Add(new TNamed("Ch10Gap3232", "Ch10Gap3232")); oba->Add(new TNamed("Ch10Gap4242", "Ch10Gap4242")); oba->Add(new TNamed("Ch10Gap24", "Ch10Gap24")); + std::vector UserDefineGFWCorr = cfgUserDefineGFWCorr; + std::vector UserDefineGFWName = cfgUserDefineGFWName; + if (!UserDefineGFWCorr.empty() && !UserDefineGFWName.empty()) { + for (int i = 0; i < UserDefineGFWName.size(); i++) { + oba->Add(new TNamed(UserDefineGFWName.at(i).c_str(), UserDefineGFWName.at(i).c_str())); + } + } fFC->SetName("FlowContainer"); fFC->SetXAxis(fPtAxis); - fFC->Initialize(oba, axisCentrality, cfgNbootstrap); + fFC->Initialize(oba, axisIndependent, cfgNbootstrap); delete oba; // eta region fGFW->AddRegion("full", -0.8, 0.8, 1, 1); + fGFW->AddRegion("refN00", -0.8, 0., 1, 1); // gap0 negative region + fGFW->AddRegion("refP00", 0., 0.8, 1, 1); // gap0 positve region + fGFW->AddRegion("refN02", -0.8, -0.1, 1, 1); // gap2 negative region + fGFW->AddRegion("refP02", 0.1, 0.8, 1, 1); // gap2 positve region fGFW->AddRegion("refN04", -0.8, -0.2, 1, 1); // gap4 negative region fGFW->AddRegion("refP04", 0.2, 0.8, 1, 1); // gap4 positve region fGFW->AddRegion("refN06", -0.8, -0.3, 1, 1); // gap6 negative region @@ -265,8 +278,11 @@ struct FlowTask { fGFW->AddRegion("refP08", 0.4, 0.8, 1, 1); fGFW->AddRegion("refN10", -0.8, -0.5, 1, 1); fGFW->AddRegion("refP10", 0.5, 0.8, 1, 1); - fGFW->AddRegion("refP", 0.4, 0.8, 1, 1); + fGFW->AddRegion("refN12", -0.8, -0.6, 1, 1); + fGFW->AddRegion("refP12", 0.6, 0.8, 1, 1); fGFW->AddRegion("refN", -0.8, -0.4, 1, 1); + fGFW->AddRegion("refP", 0.4, 0.8, 1, 1); + fGFW->AddRegion("refM", -0.4, 0.4, 1, 1); fGFW->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); fGFW->AddRegion("olN", -0.8, -0.4, 1, 4); @@ -302,6 +318,18 @@ struct FlowTask { corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {3 2} refP10 {-3 -2}", "Ch10Gap3232", kFALSE)); 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)); + if (!UserDefineGFWCorr.empty() && !UserDefineGFWName.empty()) { + LOGF(info, "User adding GFW CorrelatorConfig:"); + // attentaion: here we follow the index of cfgUserDefineGFWCorr + for (int i = 0; i < UserDefineGFWCorr.size(); i++) { + if (i >= UserDefineGFWName.size()) { + LOGF(fatal, "The names you provided are more than configurations. UserDefineGFWName.size(): %d > UserDefineGFWCorr.size(): %d", UserDefineGFWName.size(), UserDefineGFWCorr.size()); + break; + } + LOGF(info, "%d: %s %s", i, UserDefineGFWCorr.at(i).c_str(), UserDefineGFWName.at(i).c_str()); + corrconfigs.push_back(fGFW->GetCorrelatorConfig(UserDefineGFWCorr.at(i).c_str(), UserDefineGFWName.at(i).c_str(), kFALSE)); + } + } fGFW->CreateRegions(); if (cfgUseAdditionalEventCut) { @@ -613,6 +641,9 @@ struct FlowTask { // magnet field dependence cut Magnetfield = getMagneticField(bc.timestamp()); } + float independent = cent; + if (cfgUseNch) + independent = static_cast(tracks.size()); for (auto& track : tracks) { if (track.tpcNClsFound() < cfgCutTPCclu) @@ -661,19 +692,19 @@ struct FlowTask { // Filling TProfile // MeanPt if (weffEvent > 1e-6) - registry.fill(HIST("hMeanPt"), cent, ptSum / weffEvent, weffEvent); + registry.fill(HIST("hMeanPt"), independent, ptSum / weffEvent, weffEvent); if (weffEvent_WithinGap08 > 1e-6) - registry.fill(HIST("hMeanPtWithinGap08"), cent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); + registry.fill(HIST("hMeanPtWithinGap08"), independent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); // v22-Pt // c22_gap8 * pt_withGap8 if (weffEvent_WithinGap08 > 1e-6) - FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, HIST("c22_gap08_Weff"), HIST("c22_gap08_trackMeanPt"), cent); + FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, HIST("c22_gap08_Weff"), HIST("c22_gap08_trackMeanPt"), independent); // PtVariance if (WeffEvent_diff_WithGap08 > 1e-6) { - registry.fill(HIST("PtVariance_partA_WithinGap08"), cent, + registry.fill(HIST("PtVariance_partA_WithinGap08"), independent, (ptSum_Gap08 * ptSum_Gap08 - sum_ptSquare_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, WeffEvent_diff_WithGap08); - registry.fill(HIST("PtVariance_partB_WithinGap08"), cent, + registry.fill(HIST("PtVariance_partB_WithinGap08"), independent, (weffEvent_WithinGap08 * ptSum_Gap08 - sum_pt_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, WeffEvent_diff_WithGap08); } @@ -681,21 +712,21 @@ struct FlowTask { // Filling Bootstrap Samples int SampleIndex = static_cast(cfgNbootstrap * l_Random); if (weffEvent_WithinGap08 > 1e-6) - BootstrapArray[SampleIndex][kMeanPt_InGap08]->Fill(cent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); + BootstrapArray[SampleIndex][kMeanPt_InGap08]->Fill(independent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); if (weffEvent_WithinGap08 > 1e-6) - FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, BootstrapArray[SampleIndex][kC22_Gap08_Weff], BootstrapArray[SampleIndex][kC22_Gap08_MeanPt], cent); + FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, BootstrapArray[SampleIndex][kC22_Gap08_Weff], BootstrapArray[SampleIndex][kC22_Gap08_MeanPt], independent); if (WeffEvent_diff_WithGap08 > 1e-6) { - BootstrapArray[SampleIndex][kPtVarParA_InGap08]->Fill(cent, + BootstrapArray[SampleIndex][kPtVarParA_InGap08]->Fill(independent, (ptSum_Gap08 * ptSum_Gap08 - sum_ptSquare_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, WeffEvent_diff_WithGap08); - BootstrapArray[SampleIndex][kPtVarParB_InGap08]->Fill(cent, + BootstrapArray[SampleIndex][kPtVarParB_InGap08]->Fill(independent, (weffEvent_WithinGap08 * ptSum_Gap08 - sum_pt_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, WeffEvent_diff_WithGap08); } // Filling Flow Container for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - FillFC(corrconfigs.at(l_ind), cent, l_Random); + FillFC(corrconfigs.at(l_ind), independent, l_Random); } } }; diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx index 4faf529cbc5..6088da403a4 100644 --- a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx @@ -106,19 +106,22 @@ void FlowPtContainer::Initialise(const o2::framework::AxisSpec axis, const int& delete fCovList; fCovList = new TList(); fCovList->SetOwner(kTRUE); - for (int m = 0; m < mpar; ++m) + for (int m = 0; m < mpar; ++m) { fCorrList->Add(new BootstrapProfile(Form("mpt%i", m + 1), Form("corr_%ipar", m + 1), nMultiBins, &multiBins[0])); + } for (int m = 0; m < 4; ++m) { - for (int i = 0; i <= m; ++i) + for (int i = 0; i <= m; ++i) { fCMTermList->Add(new BootstrapProfile(Form("cm%i_Mpt%i", m + 1, i), Form("cm%i_Mpt%i", m + 1, i), nMultiBins, &multiBins[0])); + } } for (int i = 0; i < configs.GetSize(); ++i) { for (auto m(1); m <= mpar; ++m) { if (!(configs.GetpTCorrMasks()[i] & (1 << (m - 1)))) continue; if (fUseCentralMoments) { - for (auto j = 0; j < m; ++j) + for (auto j = 0; j < m; ++j) { fCovList->Add(new BootstrapProfile(Form("%spt%i_Mpt%i", configs.GetHeads()[i].c_str(), m, m - j - 1), Form("%spt%i_Mpt%i", configs.GetHeads()[i].c_str(), m, m - j - 1), nMultiBins, &multiBins[0])); + } } else { fCovList->Add(new BootstrapProfile(Form("%spt%i", configs.GetHeads()[i].c_str(), m), Form("%spt%i", configs.GetHeads()[i].c_str(), m), nMultiBins, &multiBins[0])); } @@ -147,19 +150,22 @@ void FlowPtContainer::Initialise(int nbinsx, double* xbins, const int& m, const delete fCorrList; fCorrList = new TList(); fCorrList->SetOwner(kTRUE); - for (int m = 0; m < mpar; ++m) + for (int m = 0; m < mpar; ++m) { fCorrList->Add(new BootstrapProfile(Form("mpt%i", m + 1), Form("mpt%i", m + 1), nbinsx, xbins)); + } for (int m = 0; m < 4; ++m) { - for (int i = 0; i <= m; ++i) + for (int i = 0; i <= m; ++i) { fCMTermList->Add(new BootstrapProfile(Form("cm%i_Mpt%i", m + 1, i), Form("cm%i_Mpt%i", m + 1, i), nbinsx, xbins)); + } } for (int i = 0; i < configs.GetSize(); ++i) { for (auto m(1); m <= mpar; ++m) { if (!(configs.GetpTCorrMasks()[i] & (1 << (m - 1)))) continue; if (fUseCentralMoments) { - for (auto j = 0; j < m; ++j) + for (auto j = 0; j < m; ++j) { fCovList->Add(new BootstrapProfile(Form("%spt%i_Mpt%i", configs.GetHeads()[i].c_str(), m, m - j - 1), Form("%spt%i_Mpt%i", configs.GetHeads()[i].c_str(), m, m - j - 1), nbinsx, xbins)); + } } else { fCovList->Add(new BootstrapProfile(Form("%spt%i", configs.GetHeads()[i].c_str(), m), Form("%spt%i", configs.GetHeads()[i].c_str(), m), nbinsx, xbins)); } @@ -187,19 +193,22 @@ void FlowPtContainer::Initialise(int nbinsx, double xlow, double xhigh, const in delete fCorrList; fCorrList = new TList(); fCorrList->SetOwner(kTRUE); - for (int m = 0; m < mpar; ++m) + for (int m = 0; m < mpar; ++m) { fCorrList->Add(new BootstrapProfile(Form("mpt%i", m + 1), Form("mpt%i", m + 1), nbinsx, xlow, xhigh)); + } for (int m = 0; m < 4; ++m) { - for (int i = 0; i <= m; ++i) + for (int i = 0; i <= m; ++i) { fCMTermList->Add(new BootstrapProfile(Form("cm%i_Mpt%i", m + 1, i), Form("cm%i_Mpt%i", m + 1, i), nbinsx, xlow, xhigh)); + } } for (int i = 0; i < configs.GetSize(); ++i) { for (auto m(1); m <= mpar; ++m) { if (!(configs.GetpTCorrMasks()[i] & (1 << (m - 1)))) continue; if (fUseCentralMoments) { - for (auto j = 0; j < m; ++j) + for (auto j = 0; j < m; ++j) { fCovList->Add(new BootstrapProfile(Form("%spt%i_Mpt%i", configs.GetHeads()[i].c_str(), m, m - j - 1), Form("%spt%i_Mpt%i", configs.GetHeads()[i].c_str(), m, m - j - 1), nbinsx, xlow, xhigh)); + } } else { fCovList->Add(new BootstrapProfile(Form("%spt%i", configs.GetHeads()[i].c_str(), m), Form("%spt%i", configs.GetHeads()[i].c_str(), m), nbinsx, xlow, xhigh)); } @@ -217,7 +226,7 @@ void FlowPtContainer::Initialise(int nbinsx, double xlow, double xhigh, const in }; void FlowPtContainer::Fill(const double& w, const double& pt) { - for (auto i = 0; i < sumP.size(); ++i) { + for (size_t i = 0; i < sumP.size(); ++i) { sumP[i] += pow(w, i % (mpar + 1)) * pow(pt, i / (mpar + 1)); } return; @@ -279,7 +288,7 @@ void FlowPtContainer::FillVnDeltaPtProfiles(const double& centmult, const double continue; for (auto i = 0; i < m; ++i) { if (cmDen[m - 1] != 0) - dynamic_cast(fCovList->At(fillCounter))->FillProfile(centmult, flowval * cmNum[m * (m - 1) / 2 + i], (fEventWeight == kUnity) ? 1.0 : flowtuples * cmDen[m - 1], rn); + dynamic_cast(fCovList->At(fillCounter))->FillProfile(centmult, flowval * cmNum[m * (m - 1) / 2 + (m - i)], (fEventWeight == kUnity) ? 1.0 : flowtuples * cmDen[m - 1], rn); ++fillCounter; } } @@ -332,7 +341,7 @@ double FlowPtContainer::OrderedAddition(std::vector vec) { double sum = 0; std::sort(vec.begin(), vec.end()); - for (int i = 0; i < vec.size(); i++) { + for (size_t i = 0; i < vec.size(); i++) { sum += vec[i]; } return sum; diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.h b/PWGCF/GenericFramework/Core/FlowPtContainer.h index fa9a46e200b..18cf8ae82ea 100644 --- a/PWGCF/GenericFramework/Core/FlowPtContainer.h +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.h @@ -81,6 +81,8 @@ class FlowPtContainer : public TNamed { sumP.clear(); sumP.resize((mpar + 1) * (mpar + 1)); + cmNum.clear(); + cmDen.clear(); fillCounter = 0; }; diff --git a/PWGCF/GenericFramework/Core/GFWConfig.h b/PWGCF/GenericFramework/Core/GFWConfig.h index 9c086acbef1..779d06b604e 100644 --- a/PWGCF/GenericFramework/Core/GFWConfig.h +++ b/PWGCF/GenericFramework/Core/GFWConfig.h @@ -35,7 +35,7 @@ int CheckSameSize(const std::vector& first) template int CheckSameSize(const std::vector& first, const std::vector&... rest) { - int size = first.size(); + size_t size = first.size(); bool allSameSize = ((size == rest.size()) && ...); return allSameSize ? size : -1; @@ -145,7 +145,7 @@ class GFWRegions auto Print() const { - for (auto i = 0; i < names.size(); ++i) { + for (size_t i = 0; i < names.size(); ++i) { LOGF(info, "{%s, %.1f, %.1f, %d, %d}", names[i].c_str(), etaminvals[i], etamaxvals[i], pTDifs[i], bitmasks[i]); } return; @@ -190,7 +190,7 @@ class GFWCorrConfigs auto Print() const { - for (auto i = 0; i < corrs.size(); ++i) { + for (size_t i = 0; i < corrs.size(); ++i) { LOGF(info, "{%s,%s,%d,%d}", heads[i].c_str(), corrs[i].c_str(), pTDifs[i], pTCorrMasks[i]); } return; diff --git a/PWGCF/GenericFramework/Core/GFWPowerArray.cxx b/PWGCF/GenericFramework/Core/GFWPowerArray.cxx index 82291e507a2..609b235ec6f 100644 --- a/PWGCF/GenericFramework/Core/GFWPowerArray.cxx +++ b/PWGCF/GenericFramework/Core/GFWPowerArray.cxx @@ -52,7 +52,7 @@ void GFWPowerArray::RecursiveFunction(HarSet& masterVector, HarSet hars, int off { HarSet compVec = AddConstant(hars, offset); FlushVectorToMaster(masterVector, compVec, MaxPower); - for (int i = 0; i < hars.size(); i++) + for (size_t i = 0; i < hars.size(); i++) RecursiveFunction(masterVector, TrimVec(hars, i), offset + hars.at(i), MaxPower); ; }; diff --git a/PWGCF/TableProducer/dptdptfilter.h b/PWGCF/TableProducer/dptdptfilter.h index 8866784f1e4..60fb6e592c4 100644 --- a/PWGCF/TableProducer/dptdptfilter.h +++ b/PWGCF/TableProducer/dptdptfilter.h @@ -840,7 +840,7 @@ inline bool matchTrackType(TrackObject const& track) } }; auto checkDcaZcut = [&](auto const& track) { - return ((maxDcaZPtDep) ? abs(track.dcaZ()) <= maxDcaZPtDep(track.pt()) : true); + return ((maxDcaZPtDep) ? std::fabs(track.dcaZ()) <= maxDcaZPtDep(track.pt()) : true); }; /* tight pT dependent DCAz cut */ diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index 2d4bd15a61d..b530c3d8fa8 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -131,10 +131,10 @@ struct lambdaCorrTableProducer { // Collisions Configurable cfg_z_vtx{"cfg_z_vtx", 10.0, "z vertex cut"}; + Configurable cfg_sel8_sel{"cfg_sel8_sel", true, "Sel8 (T0A + T0C) Selection"}; Configurable cfg_trigger_tvx_sel{"cfg_trigger_tvx_sel", false, "Trigger Time and Vertex Selection"}; Configurable cfg_tf_border{"cfg_tf_border", false, "Timeframe Border Selection"}; Configurable cfg_noitsro_border{"cfg_noitsro_border", false, "No ITSRO Border Cut"}; - Configurable cfg_sel8_sel{"cfg_sel8_sel", true, "Sel8 (T0A + T0C) Selection"}; Configurable cfg_itstpc_vtx{"cfg_itstpc_vtx", false, "ITS+TPC Vertex Selection"}; Configurable cfg_pileup_reject{"cfg_pileup_reject", false, "Pileup rejection"}; Configurable cfg_zvtx_time_diff{"cfg_zvtx_time_diff", false, "z-vtx time diff selection"}; @@ -146,6 +146,7 @@ struct lambdaCorrTableProducer { Configurable cfg_min_crossed_rows{"cfg_min_crossed_rows", 70, "min crossed rows"}; Configurable cfg_tpc_nsigma{"cfg_tpc_nsigma", 3.0, "TPC NSigma Selection Cut"}; Configurable cfg_tof_nsigma{"cfg_tof_nsigma", 3.0, "TOF NSigma Selection Cut"}; + Configurable cfg_tpc_only{"cfg_tpc_only", true, "TPC Only Selection"}; // V0s Configurable cfg_min_dca_V0_daughters{"cfg_min_dca_V0_daughters", 1.0, "min DCA between V0 daughters"}; @@ -161,8 +162,8 @@ struct lambdaCorrTableProducer { Configurable cfg_kshort_rej{"cfg_kshort_rej", 0.005, "Reject K0Short Candidates"}; // V0s kinmatic acceptance - Configurable cfg_v0_pt_min{"cfg_v0_pt_min", 0.5, "Minimum V0 pT"}; - Configurable cfg_v0_pt_max{"cfg_v0_pt_max", 2.5, "Minimum V0 pT"}; + Configurable cfg_v0_pt_min{"cfg_v0_pt_min", 0.3, "Minimum V0 pT"}; + Configurable cfg_v0_pt_max{"cfg_v0_pt_max", 3.0, "Minimum V0 pT"}; Configurable cfg_v0_rap_max{"cfg_v0_rap_max", 0.8, "|rap| cut"}; // bool eta/rapidity @@ -171,6 +172,7 @@ struct lambdaCorrTableProducer { // V0s MC Configurable cfg_is_primary_lambda{"cfg_is_primary_lambda", true, "Primary Lambda"}; Configurable cfg_casc_lambda{"cfg_casc_lambda", false, "Lambda from Cascade"}; + Configurable cfg_has_mc_flag{"cfg_has_mc_flag", false, "Has Mc Tag"}; // lambda mass windows Configurable> cfg_lambda_mass{"cfg_lambda_mass", {1.11, 1.12}, "Minimum Central Window"}; @@ -188,6 +190,7 @@ struct lambdaCorrTableProducer { // global variable mass_win_map = {{kCentralWindow, cfg_lambda_mass}, {kLeftWindow, cfg_lambda_left}, {kRightWindow, cfg_lambda_right}}; + const AxisSpec axisCol(5, 0, 5, ""); const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); const AxisSpec axisMult(10, 0, 10, "N_{#Lambda}"); const AxisSpec axisVz(220, -11, 11, "V_{z} (cm)"); @@ -213,27 +216,26 @@ struct lambdaCorrTableProducer { // Create Histograms. // Event histograms histos.add("Event/h1d_collision_posZ", "V_{z}-distribution", kTH1F, {axisVz}); + histos.add("Event/h1d_collisions_info", "# of Collisions", kTH1F, {axisCol}); // QA + histos.add("QA_Checks/h1d_tracks_info", "# of tracks", kTH1F, {axisCol}); histos.add("QA_Checks/h1d_lambda_mass", "M_{#Lambda}", kTH1F, {axisV0Mass}); + histos.add("QA_Checks/h2d_n1_V0_ptmass", "p_{T} vs M_{#Lambda}", kTH2F, {axisV0Mass, axisV0Pt}); histos.add("QA_Checks/h2d_before_topo_cuts_pt_vs_alpha", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); histos.add("QA_Checks/h2d_after_topo_cuts_pt_vs_alpha", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); histos.add("QA_Checks/h2d_before_masswincut_pt_vs_alpha", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); histos.add("QA_Checks/h2d_after_masswincut_pt_vs_alpha", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); // QA Lambda - histos.add("QA_Sel_Lambda/h1d_pos_prong_pt", "Pos-Prong p_{T}", kTH1F, {axisV0Pt}); - histos.add("QA_Sel_Lambda/h1d_neg_prong_pt", "Neg-Prong p_{T}", kTH1F, {axisV0Pt}); - histos.add("QA_Sel_Lambda/h1d_pos_prong_eta", "Pos-Prong #eta-distribution", kTH1F, {axisV0Rap}); - histos.add("QA_Sel_Lambda/h1d_neg_prong_eta", "Neg-Prong #eta-distribution", kTH1F, {axisV0Rap}); - histos.add("QA_Sel_Lambda/h1d_pos_prong_phi", "Pos-Prong #phi-distribution", kTH1F, {axisV0Phi}); - histos.add("QA_Sel_Lambda/h1d_neg_prong_phi", "Neg-Prong #phi-distribution", kTH1F, {axisV0Phi}); - histos.add("QA_Sel_Lambda/h1d_V0_inv_mass", "V_{0} mass", kTH1F, {axisV0Mass}); histos.add("QA_Sel_Lambda/h1d_V0_pt", "V_{0} p_{T}", kTH1F, {axisV0Pt}); histos.add("QA_Sel_Lambda/h1d_V0_eta", "#eta-distribution", kTH1F, {axisV0Rap}); histos.add("QA_Sel_Lambda/h1d_V0_rap", "y-distribution", kTH1F, {axisV0Rap}); histos.add("QA_Sel_Lambda/h1d_V0_phi", "#phi-distribution", kTH1F, {axisV0Phi}); + histos.add("QA_Sel_Lambda/h2d_n1_V0_pteta", "p_{T} vs #eta", kTH2F, {axisV0Rap, axisV0Pt}); + histos.add("QA_Sel_Lambda/h2d_n1_V0_ptrap", "p_{T} vs y", kTH2F, {axisV0Rap, axisV0Pt}); + histos.add("QA_Sel_Lambda/h2d_n1_V0_ptphi", "p_{T} vs #phi", kTH2F, {axisV0Phi, axisV0Pt}); histos.add("QA_Sel_Lambda/h1d_dca_V0_daughters", "DCA between V0 daughters", kTH1F, {axisDcaDau}); histos.add("QA_Sel_Lambda/h1d_dca_pos_to_PV", "DCA positive prong to PV", kTH1F, {axisDcaProngPV}); @@ -243,6 +245,13 @@ struct lambdaCorrTableProducer { histos.add("QA_Sel_Lambda/h1d_V0_radius", "V_{0} Decay Radius in XY plane", kTH1F, {axisRadius}); histos.add("QA_Sel_Lambda/h1d_V0_ctau", "V_{0} c#tau", kTH1F, {axisCTau}); + histos.add("QA_Sel_Lambda/h1d_pos_prong_pt", "Pos-Prong p_{T}", kTH1F, {axisV0Pt}); + histos.add("QA_Sel_Lambda/h1d_neg_prong_pt", "Neg-Prong p_{T}", kTH1F, {axisV0Pt}); + histos.add("QA_Sel_Lambda/h1d_pos_prong_eta", "Pos-Prong #eta-distribution", kTH1F, {axisV0Rap}); + histos.add("QA_Sel_Lambda/h1d_neg_prong_eta", "Neg-Prong #eta-distribution", kTH1F, {axisV0Rap}); + histos.add("QA_Sel_Lambda/h1d_pos_prong_phi", "Pos-Prong #phi-distribution", kTH1F, {axisV0Phi}); + histos.add("QA_Sel_Lambda/h1d_neg_prong_phi", "Neg-Prong #phi-distribution", kTH1F, {axisV0Phi}); + histos.add("QA_Sel_Lambda/h2d_pos_prong_dEdx_vs_p", "TPC Signal Pos-Prong", kTH2F, {axisMomPID, axisdEdx}); histos.add("QA_Sel_Lambda/h2d_neg_prong_dEdx_vs_p", "TPC Signal Neg-Prong", kTH2F, {axisMomPID, axisdEdx}); histos.add("QA_Sel_Lambda/h2d_pos_prong_nsigma_pr_tpc", "TPC n#sigma Pos-Prong", kTH2F, {axisMomPID, axisNsigma}); @@ -261,15 +270,22 @@ struct lambdaCorrTableProducer { // MC Generated Histograms if (doprocessMCGen) { - histos.add("MCGen/h1d_collision_posZ", "V_{z}-distribution", kTH1F, {axisVz}); - histos.add("MCGen/h1d_pt_lambda", "#Lambda p_{T}", kTH1F, {axisV0Pt}); - histos.add("MCGen/h1d_pt_antilambda", "#bar{#Lambda} p_{T}", kTH1F, {axisV0Pt}); - histos.add("MCGen/h1d_eta_lambda", "#Lambda #eta-distribution", kTH1F, {axisV0Rap}); - histos.add("MCGen/h1d_eta_antilambda", "#bar{#Lambda} #eta-distribution", kTH1F, {axisV0Rap}); - histos.add("MCGen/h1d_y_lambda", "#Lambda y-distribution", kTH1F, {axisV0Rap}); - histos.add("MCGen/h1d_y_antilambda", "#bar{#Lambda} y-distribution", kTH1F, {axisV0Rap}); - histos.add("MCGen/h1d_phi_lambda", "#Lambda #phi-distribution", kTH1F, {axisV0Phi}); - histos.add("MCGen/h1d_phi_antilambda", "#bar{#Lambda} #phi-distribution", kTH1F, {axisV0Phi}); + histos.add("McGen/h1d_collisions_info", "# of collisions", kTH1F, {axisCol}); + histos.add("McGen/h1d_collision_posZ", "V_{z}-distribution", kTH1F, {axisVz}); + histos.add("McGen/h1d_pt_lambda", "#Lambda p_{T}", kTH1F, {axisV0Pt}); + histos.add("McGen/h1d_eta_lambda", "#Lambda #eta-distribution", kTH1F, {axisV0Rap}); + histos.add("McGen/h1d_y_lambda", "#Lambda y-distribution", kTH1F, {axisV0Rap}); + histos.add("McGen/h1d_phi_lambda", "#Lambda #phi-distribution", kTH1F, {axisV0Phi}); + histos.add("McGen/h2d_pteta_lambda", "#Lambda p_{T} vs #eta", kTH2F, {axisV0Rap, axisV0Pt}); + histos.add("McGen/h2d_ptrap_lambda", "#Lambda p_{T} vs y", kTH2F, {axisV0Rap, axisV0Pt}); + histos.add("McGen/h2d_ptphi_lambda", "#Lambda p_{T} vs #phi", kTH2F, {axisV0Phi, axisV0Pt}); + histos.add("McGen/h1d_pt_antilambda", "#bar{#Lambda} p_{T}", kTH1F, {axisV0Pt}); + histos.add("McGen/h1d_eta_antilambda", "#bar{#Lambda} #eta-distribution", kTH1F, {axisV0Rap}); + histos.add("McGen/h1d_y_antilambda", "#bar{#Lambda} y-distribution", kTH1F, {axisV0Rap}); + histos.add("McGen/h1d_phi_antilambda", "#bar{#Lambda} #phi-distribution", kTH1F, {axisV0Phi}); + histos.add("McGen/h2d_pteta_antilambda", "#bar{#Lambda} p_{T} vs #eta", kTH2F, {axisV0Rap, axisV0Pt}); + histos.add("McGen/h2d_ptrap_antilambda", "#bar{#Lambda} p_{T} vs y", kTH2F, {axisV0Rap, axisV0Pt}); + histos.add("McGen/h2d_ptphi_antilambda", "#bar{#Lambda} p_{T} vs #phi", kTH2F, {axisV0Phi, axisV0Pt}); } } @@ -390,7 +406,7 @@ struct lambdaCorrTableProducer { break; } - if (track.hasTOF()) { + if (!cfg_tpc_only && track.hasTOF()) { if (fabs(tofNSigma) < cfg_tof_nsigma) { selTOFv0type = true; } @@ -438,6 +454,9 @@ struct lambdaCorrTableProducer { histos.fill(HIST(sub_dir[part]) + HIST("h1d_V0_rap"), v0.yLambda()); histos.fill(HIST(sub_dir[part]) + HIST("h1d_V0_phi"), v0.phi()); histos.fill(HIST(sub_dir[part]) + HIST("h2d_pt_vs_alpha"), v0.alpha(), v0.qtarm()); + histos.fill(HIST(sub_dir[part]) + HIST("h2d_n1_V0_pteta"), v0.eta(), v0.pt()); + histos.fill(HIST(sub_dir[part]) + HIST("h2d_n1_V0_ptrap"), v0.yLambda(), v0.pt()); + histos.fill(HIST(sub_dir[part]) + HIST("h2d_n1_V0_ptphi"), v0.phi(), v0.pt()); histos.fill(HIST(sub_dir[part]) + HIST("h1d_dca_V0_daughters"), v0.dcaV0daughters()); histos.fill(HIST(sub_dir[part]) + HIST("h1d_dca_pos_to_PV"), fabs(v0.dcapostopv())); @@ -462,12 +481,12 @@ struct lambdaCorrTableProducer { histos.fill(HIST(sub_dir[part]) + HIST("h2d_neg_prong_nsigma_pr_tpc"), negtrack.tpcInnerParam(), negtrack.tpcNSigmaPr()); histos.fill(HIST(sub_dir[part]) + HIST("h2d_neg_prong_nsigma_pi_tpc"), negtrack.tpcInnerParam(), negtrack.tpcNSigmaPi()); - if (postrack.hasTOF()) { + if (!cfg_tpc_only && postrack.hasTOF()) { histos.fill(HIST(sub_dir[part]) + HIST("h2d_pos_prong_nsigma_pr_tof"), postrack.tofExpMom(), postrack.tofNSigmaPr()); histos.fill(HIST(sub_dir[part]) + HIST("h2d_pos_prong_nsigma_pi_tof"), postrack.tofExpMom(), postrack.tofNSigmaPi()); } - if (negtrack.hasTOF()) { + if (!cfg_tpc_only && negtrack.hasTOF()) { histos.fill(HIST(sub_dir[part]) + HIST("h2d_neg_prong_nsigma_pr_tof"), negtrack.tofExpMom(), negtrack.tofNSigmaPr()); histos.fill(HIST(sub_dir[part]) + HIST("h2d_neg_prong_nsigma_pi_tof"), negtrack.tofExpMom(), negtrack.tofNSigmaPi()); } @@ -496,6 +515,7 @@ struct lambdaCorrTableProducer { return; } + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 3.5); histos.fill(HIST("QA_Checks/h2d_before_masswincut_pt_vs_alpha"), v0track.alpha(), v0track.qtarm()); // apply mass window selection [global] @@ -521,6 +541,8 @@ struct lambdaCorrTableProducer { return; } + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 4.5); + // apply MC Reco cuts if constexpr (reco) { @@ -540,7 +562,9 @@ struct lambdaCorrTableProducer { } // fill mass histogram before mass window cuts + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 5.5); histos.fill(HIST("QA_Checks/h1d_lambda_mass"), mass); + histos.fill(HIST("QA_Checks/h2d_n1_V0_ptmass"), mass, v0track.pt()); // loop over mass windows for (auto m = mass_win_map.begin(); m != mass_win_map.end(); ++m) { @@ -569,17 +593,21 @@ struct lambdaCorrTableProducer { void processData(Collisions::iterator const& collision, aod::V0Datas const& V0s, Tracks const& tracks) { + histos.fill(HIST("Event/h1d_collisions_info"), 1.5); + // select collision if (!selCol(collision)) { return; } + histos.fill(HIST("Event/h1d_collisions_info"), 2.5); histos.fill(HIST("Event/h1d_collision_posZ"), collision.posZ()); lambdaCollisionTable(collision.centFT0M(), collision.posX(), collision.posY(), collision.posZ()); for (auto const& v0 : V0s) { + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 1.5); histos.fill(HIST("QA_Checks/h2d_before_topo_cuts_pt_vs_alpha"), v0.alpha(), v0.qtarm()); // apply topological cuts on v0 candidates @@ -587,6 +615,7 @@ struct lambdaCorrTableProducer { continue; } + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 2.5); histos.fill(HIST("QA_Checks/h2d_after_topo_cuts_pt_vs_alpha"), v0.alpha(), v0.qtarm()); selV0Particle(collision, v0, tracks); @@ -613,16 +642,21 @@ struct lambdaCorrTableProducer { for (auto const& collision : collisions) { - // check for corresponding MCGen Collision - if (!collision.has_mcCollision()) { - return; - } + histos.fill(HIST("Event/h1d_collisions_info"), 1.5); // select collision if (!selCol(collision)) { - return; + continue; + } + + histos.fill(HIST("Event/h1d_collisions_info"), 2.5); + + // check for corresponding MCGen Collision + if (cfg_has_mc_flag && !collision.has_mcCollision()) { + continue; } + histos.fill(HIST("Event/h1d_collisions_info"), 3.5); histos.fill(HIST("Event/h1d_collision_posZ"), collision.posZ()); lambdaCollisionTable(collision.centFT0M(), collision.posX(), collision.posY(), collision.posZ()); @@ -633,11 +667,14 @@ struct lambdaCorrTableProducer { auto v0sThisCollision = V0s.sliceBy(perCol, collision.globalIndex()); for (auto const& v0 : v0sThisCollision) { + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 0.5); + // check for corresponding MCGen Particle - if (!v0.has_mcParticle()) { + if (cfg_has_mc_flag && !v0.has_mcParticle()) { continue; } + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 1.5); histos.fill(HIST("QA_Checks/h2d_before_topo_cuts_pt_vs_alpha"), v0.alpha(), v0.qtarm()); // apply topological cuts on v0 candidates @@ -645,6 +682,7 @@ struct lambdaCorrTableProducer { continue; } + histos.fill(HIST("QA_Checks/h1d_tracks_info"), 2.5); histos.fill(HIST("QA_Checks/h2d_after_topo_cuts_pt_vs_alpha"), v0.alpha(), v0.qtarm()); selV0Particle(collision, v0, tracks); @@ -657,12 +695,15 @@ struct lambdaCorrTableProducer { void processMCGen(McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles) { + histos.fill(HIST("McGen/h1d_collisions_info"), 1.5); + // apply collision cuts if (fabs(mcCollision.posZ()) > cfg_z_vtx) { return; } - histos.fill(HIST("MCGen/h1d_collision_posZ"), mcCollision.posZ()); + histos.fill(HIST("McGen/h1d_collisions_info"), 2.5); + histos.fill(HIST("McGen/h1d_collision_posZ"), mcCollision.posZ()); lambdaMCGenCollisionTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()); TLorentzVector p; @@ -716,16 +757,22 @@ struct lambdaCorrTableProducer { // Fill histograms if (mcpart.pdgCode() == 3122) { - histos.fill(HIST("MCGen/h1d_pt_lambda"), mcpart.pt()); - histos.fill(HIST("MCGen/h1d_eta_lambda"), mcpart.eta()); - histos.fill(HIST("MCGen/h1d_y_lambda"), mcpart.y()); - histos.fill(HIST("MCGen/h1d_phi_lambda"), mcpart.phi()); + histos.fill(HIST("McGen/h1d_pt_lambda"), mcpart.pt()); + histos.fill(HIST("McGen/h1d_eta_lambda"), mcpart.eta()); + histos.fill(HIST("McGen/h1d_y_lambda"), mcpart.y()); + histos.fill(HIST("McGen/h1d_phi_lambda"), mcpart.phi()); + histos.fill(HIST("McGen/h2d_pteta_lambda"), mcpart.eta(), mcpart.pt()); + histos.fill(HIST("McGen/h2d_ptrap_lambda"), mcpart.y(), mcpart.pt()); + histos.fill(HIST("McGen/h2d_ptphi_lambda"), mcpart.phi(), mcpart.pt()); lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), rap, mcpart.phi(), p.M(), postrackid, negtrackid, (int8_t)kLambda); } else if (mcpart.pdgCode() == -3122) { - histos.fill(HIST("MCGen/h1d_pt_antilambda"), mcpart.pt()); - histos.fill(HIST("MCGen/h1d_eta_antilambda"), mcpart.eta()); - histos.fill(HIST("MCGen/h1d_y_antilambda"), mcpart.y()); - histos.fill(HIST("MCGen/h1d_phi_antilambda"), mcpart.phi()); + histos.fill(HIST("McGen/h1d_pt_antilambda"), mcpart.pt()); + histos.fill(HIST("McGen/h1d_eta_antilambda"), mcpart.eta()); + histos.fill(HIST("McGen/h1d_y_antilambda"), mcpart.y()); + histos.fill(HIST("McGen/h1d_phi_antilambda"), mcpart.phi()); + histos.fill(HIST("McGen/h2d_pteta_antilambda"), mcpart.eta(), mcpart.pt()); + histos.fill(HIST("McGen/h2d_ptrap_antilambda"), mcpart.y(), mcpart.pt()); + histos.fill(HIST("McGen/h2d_ptphi_antilambda"), mcpart.phi(), mcpart.pt()); lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), rap, mcpart.phi(), p.M(), postrackid, negtrackid, (int8_t)kAntiLambda); } } @@ -777,7 +824,7 @@ struct lambdaCorrelationAnalysis { const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); const AxisSpec axisMult(10, 0, 10, "N_{#Lambda}"); const AxisSpec axisMass(100, 1.06, 1.16, "Inv Mass (GeV/#it{c}^{2})"); - const AxisSpec axisPt(40, 0.5, 2.5, "p_{T} (GeV/#it{c})"); + const AxisSpec axisPt(60, 0.2, 3.2, "p_{T} (GeV/#it{c})"); const AxisSpec axisRap(cfg_nRapBins, cfg_Rap_Min, cfg_Rap_Max, "rap"); const AxisSpec axisPhi(cfg_nPhiBins, cfg_Phi_Min, cfg_Phi_Max, "#phi (rad)"); const AxisSpec axisRapPhi(knrapphibins, kminrapphi, kmaxrapphi, "rap #phi"); @@ -796,6 +843,11 @@ struct lambdaCorrelationAnalysis { histos.addClone("Reco/Lambda/", "Reco/AntiLambda/"); // single and two particle densities + histos.add("Reco/Lambda_Mass/h2d_n1_LaP", "#rho_{1}^{#Lambda}", kTH2D, {axisRap, axisPhi}); + histos.add("Reco/Lambda_Mass/h2d_n1_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2D, {axisRap, axisPhi}); + histos.add("Reco/Lambda_Mass/h2d_n2_LaP_LaM", "#rho_{2}^{#Lambda - #bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); + histos.add("Reco/Lambda_Mass/h2d_n2_LaP_LaP", "#rho_{2}^{#Lambda - #Lambda}", kTH2D, {axisRapPhi, axisRapPhi}); + histos.add("Reco/Lambda_Mass/h2d_n2_LaM_LaM", "#rho_{2}^{#bar{#Lambda} - #bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); histos.add("Reco/Lambda_Mass/h2d_n2_pt1pt2_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisPt, axisPt}); histos.add("Reco/Lambda_Mass/h2d_n2_pt1pt2_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisPt, axisPt}); histos.add("Reco/Lambda_Mass/h2d_n2_pt1pt2_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisPt, axisPt}); @@ -811,11 +863,6 @@ struct lambdaCorrelationAnalysis { histos.add("Reco/Lambda_Mass/h2d_n2_pt1phi2_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisPt, axisPhi}); histos.add("Reco/Lambda_Mass/h2d_n2_pt1phi2_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisPt, axisPhi}); histos.add("Reco/Lambda_Mass/h2d_n2_pt1phi2_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisPt, axisPhi}); - histos.add("Reco/Lambda_Mass/h2d_n1_LaP", "#rho_{1}^{#Lambda}", kTH2D, {axisRap, axisPhi}); - histos.add("Reco/Lambda_Mass/h2d_n1_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2D, {axisRap, axisPhi}); - histos.add("Reco/Lambda_Mass/h2d_n2_LaP_LaM", "#rho_{2}^{#Lambda - #bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); - histos.add("Reco/Lambda_Mass/h2d_n2_LaP_LaP", "#rho_{2}^{#Lambda - #Lambda}", kTH2D, {axisRapPhi, axisRapPhi}); - histos.add("Reco/Lambda_Mass/h2d_n2_LaM_LaM", "#rho_{2}^{#bar{#Lambda} - #bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); histos.addClone("Reco/Lambda_Mass/", "Reco/Lambda_Right/"); histos.addClone("Reco/Lambda_Mass/", "Reco/Lambda_Left/"); @@ -865,14 +912,14 @@ struct lambdaCorrelationAnalysis { static constexpr std::string_view sub_dir_recgen[] = {"Reco/", "McGen/"}; static constexpr std::string_view sub_dir_part[] = {"Lambda/", "AntiLambda/"}; static constexpr std::string_view sub_dir_mass_win[] = {"Lambda_Mass/", "Lambda_Left/", "Lambda_Right/"}; - static constexpr std::string_view sub_dir_hist[] = {"h2d_n1_LaP", "h2d_n1_LaM"}; + static constexpr std::string_view sub_dir_hist[] = {"LaP", "LaM"}; int ntrk = 0; for (auto const& track : tracks) { ++ntrk; histos.fill(HIST(sub_dir_recgen[rec_gen]) + HIST(sub_dir_part[part]) + HIST("h1d_inv_mass"), track.mass()); - histos.fill(HIST(sub_dir_recgen[rec_gen]) + HIST(sub_dir_mass_win[masswin]) + HIST(sub_dir_hist[part]), track.rap(), track.phi()); + histos.fill(HIST(sub_dir_recgen[rec_gen]) + HIST(sub_dir_mass_win[masswin]) + HIST("h2d_n1_") + HIST(sub_dir_hist[part]), track.rap(), track.phi()); } if (masswin == kCentralWindow && ntrk != 0) { @@ -890,7 +937,7 @@ struct lambdaCorrelationAnalysis { for (auto const& trk_1 : trks_1) { for (auto const& trk_2 : trks_2) { - if (samelambda && (trk_1.index() == trk_2.index()) && (trk_1.postrackid() == trk_2.postrackid()) && (trk_1.negtrackid() == trk_2.negtrackid())) { + if (samelambda && ((trk_1.index() == trk_2.index()) || (trk_1.postrackid() == trk_2.postrackid()) || (trk_1.negtrackid() == trk_2.negtrackid()))) { continue; } fillPairHistos(trk_1, trk_2); @@ -968,8 +1015,8 @@ struct lambdaCorrelationAnalysis { analyzeSingles(lambda_mcgen_tracks); analyzeSingles(antilambda_mcgen_tracks); analyzePairs(lambda_mcgen_tracks, antilambda_mcgen_tracks); - analyzePairs(lambda_mcgen_tracks, antilambda_mcgen_tracks); - analyzePairs(lambda_mcgen_tracks, antilambda_mcgen_tracks); + analyzePairs(lambda_mcgen_tracks, lambda_mcgen_tracks); + analyzePairs(antilambda_mcgen_tracks, antilambda_mcgen_tracks); } PROCESS_SWITCH(lambdaCorrelationAnalysis, processMCGen, "Process for MC Generated", false); diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 0b25a3660d8..064f26b1938 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -370,6 +370,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("pidElectron_ionut")) { + cut->AddCut(GetAnalysisCut("pidcalib_ele")); + cut->AddCut(GetAnalysisCut("jpsiStandardKine3")); + return cut; + } + + if (!nameStr.compare("pidPion_ionut")) { + cut->AddCut(GetAnalysisCut("pidcalib_pion")); + cut->AddCut(GetAnalysisCut("jpsiStandardKine3")); + return cut; + } + if (!nameStr.compare("jpsiO2MCdebugCuts13_Corr")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); // no cut on ITS clusters @@ -877,6 +889,24 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + for (int iCut = 0; iCut < 7; iCut++) { + if (!nameStr.compare(Form("jpsiEleSel%d_ionut", iCut))) { + cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); + cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); + cut->AddCut(GetAnalysisCut("trackQuality_ionut")); + cut->AddCut(GetAnalysisCut(Form("pidJpsiEle%d_ionut", iCut))); + return cut; + } + + if (!nameStr.compare(Form("jpsiEleSelTight%d_ionut", iCut))) { + cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); + cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); + cut->AddCut(GetAnalysisCut("trackQualityTight_ionut")); + cut->AddCut(GetAnalysisCut(Form("pidJpsiEle%d_ionut", iCut))); + return cut; + } + } + //--------------------------------------------------------------- // Cuts for the selection of legs from dalitz decay // @@ -3223,6 +3253,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) if (!nameStr.compare("eventStandardSel8WithITSROFRecomputedCut")) { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); cut->AddCut(VarManager::kIsNoITSROFBorderRecomputed, 0.5, 1.5); return cut; } @@ -3992,6 +4023,76 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("trackQuality_ionut")) { + cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); + cut->AddCut(VarManager::kTPCncls, 70, 161); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 2.0); + return cut; + } + + if (!nameStr.compare("trackQualityTight_ionut")) { + cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); + cut->AddCut(VarManager::kTPCncls, 100, 161); + cut->AddCut(VarManager::kITSchi2, 0.0, 3.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 2.0); + cut->AddCut(VarManager::kITSncls, 5.0, 8.0); + return cut; + } + + if (!nameStr.compare("kineJpsiEle_ionut")) { + cut->AddCut(VarManager::kP, 1.0, 15.0); + cut->AddCut(VarManager::kEta, -0.9, 0.9); + return cut; + } + + if (!nameStr.compare("pidJpsiEle0_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0, false, VarManager::kPin, 1.0, 4.0); + cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kPin, 4.0, 150.0); + cut->AddCut(VarManager::kTPCnSigmaEl, 98.1, 98.11, false, VarManager::kPin, 0.0, 1.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + + if (!nameStr.compare("pidJpsiEle1_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 1.0, 4.0); + cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kPin, 4.0, 150.0); + cut->AddCut(VarManager::kTPCnSigmaEl, 98.1, 98.11, false, VarManager::kPin, 0.0, 1.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + + if (!nameStr.compare("pidJpsiEle2_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + + if (!nameStr.compare("pidJpsiEle3_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -0.5, 4.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + + if (!nameStr.compare("pidJpsiEle4_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, 0.0, 4.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + + if (!nameStr.compare("pidJpsiEle5_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, 0.5, 4.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + + if (!nameStr.compare("pidJpsiEle6_ionut")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0); + cut->AddCut(VarManager::kTOFnSigmaEl, -1.0, 4.0); + cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); + return cut; + } + if (!nameStr.compare("standardPrimaryTrackDCAz")) { cut->AddCut(VarManager::kTrackDCAxy, -3.0, 3.0); cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0); diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index 4e380a93090..0ee10b5f844 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -54,17 +54,17 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } if (subGroupStr.Contains("time")) { hm->AddHistogram(histClass, "CollTime", "Coll. time wrt BC", false, 100, 0.0, 100.0, VarManager::kCollisionTime); - hm->AddHistogram(histClass, "CollTimeRes", "Coll. time resolution", false, 100, 0.0, 100.0, VarManager::kCollisionTimeRes); + hm->AddHistogram(histClass, "CollTimeRes", "Coll. time resolution", false, 100, 0.0, 200.0, VarManager::kCollisionTimeRes); hm->AddHistogram(histClass, "CollTime_VtxZ", "Coll. time wrt BC vs vtx-z", false, 50, -15.0, 15., VarManager::kVtxZ, 100, 0.0, 100.0, VarManager::kCollisionTime); hm->AddHistogram(histClass, "CollTimeRes_VtxZ", "Coll. time resolution ", false, 50, -15.0, 15., VarManager::kVtxZ, 100, 0.0, 100.0, VarManager::kCollisionTimeRes); - hm->AddHistogram(histClass, "CollTimeRes_MultTPC", "Coll. time resolution ", false, 50, 0.0, 500., VarManager::kMultTPC, 100, 0.0, 100.0, VarManager::kCollisionTimeRes); - hm->AddHistogram(histClass, "CollTimeRes_MultPV", "Coll. time resolution ", false, 50, 0.0, 500., VarManager::kVtxNcontribReal, 100, 0.0, 100.0, VarManager::kCollisionTimeRes); + hm->AddHistogram(histClass, "CollTimeRes_MultTPC", "Coll. time resolution ", false, 50, 0.0, 50000., VarManager::kMultTPC, 100, 0.0, 200.0, VarManager::kCollisionTimeRes); + hm->AddHistogram(histClass, "CollTimeRes_MultPV", "Coll. time resolution ", false, 100, 0.0, 4000., VarManager::kVtxNcontribReal, 100, 0.0, 200.0, VarManager::kCollisionTimeRes); hm->AddHistogram(histClass, "TimeFromSOR", "Time since SOR", false, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR); } if (subGroupStr.Contains("vtx")) { hm->AddHistogram(histClass, "VtxX", "Vtx X", false, 200, -0.1, 0.1, VarManager::kVtxX); hm->AddHistogram(histClass, "VtxY", "Vtx Y", false, 200, -0.1, 0.1, VarManager::kVtxY); - hm->AddHistogram(histClass, "VtxYVtxX", "Vtx Y vs Vtx X", false, 100, -0.1, 0.1, VarManager::kVtxX, 100, -0.1, 0.1, VarManager::kVtxY); + hm->AddHistogram(histClass, "VtxYVtxX", "Vtx Y vs Vtx X", false, 200, -0.06, 0.0, VarManager::kVtxX, 200, -0.03, 0.03, VarManager::kVtxY); } if (subGroupStr.Contains("vtxpp")) { hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 100.0, VarManager::kVtxNcontrib); @@ -73,11 +73,9 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 20000.0, VarManager::kVtxNcontrib); } if (subGroupStr.Contains("cent")) { - hm->AddHistogram(histClass, "CentV0M", "CentV0M", false, 100, 0., 100., VarManager::kCentVZERO); - hm->AddHistogram(histClass, "CentV0M_vtxZ", "CentV0M vs Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ, 20, 0., 100., VarManager::kCentVZERO); hm->AddHistogram(histClass, "CentFT0C", "CentFT0C", false, 100, 0., 100., VarManager::kCentFT0C); hm->AddHistogram(histClass, "CentFT0C_vtxZ", "CentFT0C vs Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ, 20, 0., 100., VarManager::kCentFT0C); - hm->AddHistogram(histClass, "CentFT0C_MultTPC", "CentFT0C vs MultTPC", false, 100, 0., 100., VarManager::kCentFT0C, 50, 0., 50., VarManager::kMultTPC); + hm->AddHistogram(histClass, "CentFT0C_MultTPC", "CentFT0C vs MultTPC", false, 100, 0., 100., VarManager::kCentFT0C, 100, 0., 50000., VarManager::kMultTPC); hm->AddHistogram(histClass, "CentFT0C_Run", "Cent FT0C", true, VarManager::GetDummyNRuns(), -0.5 + VarManager::GetDummyFirst(), 0.5 + VarManager::GetDummyLast(), VarManager::kRunNo, 100, 0., 100., VarManager::kCentFT0C, 1, 0, 1, VarManager::kNothing, VarManager::GetRunStr().Data()); } if (subGroupStr.Contains("mult")) { @@ -98,25 +96,31 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } else { hm->AddHistogram(histClass, "MultTPC", "MultTPC", false, 200, 0.0, 50000.0, VarManager::kMultTPC); hm->AddHistogram(histClass, "MultTPC_vsTimeSOR", "MultTPC vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, 0.0, 50000.0, VarManager::kMultTPC); - hm->AddHistogram(histClass, "MultFV0A", "MultFV0A", false, 200, 0.0, 100000.0, VarManager::kMultFV0A); - hm->AddHistogram(histClass, "MultFT0A", "MultFT0A", false, 200, 0.0, 100000.0, VarManager::kMultFT0A); + hm->AddHistogram(histClass, "MultFV0A", "MultFV0A", false, 200, 0.0, 300000.0, VarManager::kMultFV0A); + hm->AddHistogram(histClass, "MultFT0A", "MultFT0A", false, 200, 0.0, 300000.0, VarManager::kMultFT0A); hm->AddHistogram(histClass, "MultFT0C", "MultFT0C", false, 200, 0.0, 100000.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "MultFDDA", "MultFDDA", false, 100, 0.0, 100000.0, VarManager::kMultFDDA); hm->AddHistogram(histClass, "MultFDDC", "MultFDDC", false, 100, 0.0, 100000.0, VarManager::kMultFDDC); - hm->AddHistogram(histClass, "MultZNA", "MultZNA", false, 200, 0.0, 5000.0, VarManager::kMultZNA); - hm->AddHistogram(histClass, "MultZNC", "MultZNC", false, 200, 0.0, 5000.0, VarManager::kMultZNC); + hm->AddHistogram(histClass, "MultZNA", "MultZNA", false, 400, 0.0, 400.0, VarManager::kMultZNA); + hm->AddHistogram(histClass, "MultZNC", "MultZNC", false, 400, 0.0, 400.0, VarManager::kMultZNC); + hm->AddHistogram(histClass, "MultZNA_ZNC", "MultZNA vs ZNC", false, 400, 0.0, 400.0, VarManager::kMultZNA, 400, 0.0, 400.0, VarManager::kMultZNC); hm->AddHistogram(histClass, "MultTracklets", "MultTracklets", false, 100, 0.0, 25000.0, VarManager::kMultTracklets); hm->AddHistogram(histClass, "VtxNContribReal", "Vtx n contributors (real)", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal); hm->AddHistogram(histClass, "VtxNContribReal_vsTimeSOR", "VtxNContribReal vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, 0.0, 5000.0, VarManager::kVtxNcontribReal); - hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 5000.0, VarManager::kVtxNcontrib); - hm->AddHistogram(histClass, "MultTPC_MultFV0A", "MultTPC vs MultFV0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 100000.0, VarManager::kMultFV0A); - hm->AddHistogram(histClass, "MultTPC_MultFT0A", "MultTPC vs MultFT0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 100000.0, VarManager::kMultFT0A); + hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 20000.0, VarManager::kVtxNcontrib); + hm->AddHistogram(histClass, "MultTPC_MultFV0A", "MultTPC vs MultFV0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 300000.0, VarManager::kMultFV0A); + hm->AddHistogram(histClass, "MultTPC_MultFT0A", "MultTPC vs MultFT0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 300000.0, VarManager::kMultFT0A); hm->AddHistogram(histClass, "MultTPC_MultFT0C", "MultTPC vs MultFT0C", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 100000.0, VarManager::kMultFT0C); - hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 100000.0, VarManager::kMultFT0A, 100, 0, 100000.0, VarManager::kMultFT0C); + hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 100000.0, VarManager::kMultFT0A, 100, 0, 300000.0, VarManager::kMultFT0C); + hm->AddHistogram(histClass, "VtxNContribReal_MultTPC", "Vtx n contributors (real) vs mult TPC", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal, 200, 0.0, 50000.0, VarManager::kMultTPC); + hm->AddHistogram(histClass, "VtxNContribReal_ZNA", "Vtx n contributors (real) vs ZNA", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal, 200, 0.0, 400.0, VarManager::kMultZNA); + hm->AddHistogram(histClass, "VtxNContribReal_ZNC", "Vtx n contributors (real) vs ZNC", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal, 200, 0.0, 400.0, VarManager::kMultZNC); + hm->AddHistogram(histClass, "MultZNA_FT0C", "MultZNA vs FT0C", false, 400, 0.0, 400.0, VarManager::kMultZNA, 200, 0.0, 100000.0, VarManager::kMultFT0C); + hm->AddHistogram(histClass, "MultZNC_FT0C", "MultZNC vs FT0C", false, 400, 0.0, 400.0, VarManager::kMultZNC, 200, 0.0, 100000.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "TPCpileupZA", "TPC pileup Z, A-side", false, 200, -50.0, 50.0, VarManager::kNTPCpileupZA); hm->AddHistogram(histClass, "TPCpileupZC", "TPC pileup Z, C-side", false, 200, -50.0, 50.0, VarManager::kNTPCpileupZC); - hm->AddHistogram(histClass, "TPCpileupNcontribA", "TPC pileup n-contributors, A-side", false, 1000, 0.0, 10000.0, VarManager::kNTPCpileupContribA); - hm->AddHistogram(histClass, "TPCpileupNcontribC", "TPC pileup n-contributors, C-side", false, 1000, 0.0, 10000.0, VarManager::kNTPCpileupContribC); + hm->AddHistogram(histClass, "TPCpileupNcontribA", "TPC pileup n-contributors, A-side", false, 300, 0.0, 3000.0, VarManager::kNTPCpileupContribA); + hm->AddHistogram(histClass, "TPCpileupNcontribC", "TPC pileup n-contributors, C-side", false, 300, 0.0, 3000.0, VarManager::kNTPCpileupContribC); } } if (subGroupStr.Contains("ftmulpbpb")) { @@ -452,7 +456,19 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "TPCnSigEle_pIN", "TPC n-#sigma(e) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaEl); hm->AddHistogram(histClass, "TPCnSigEle_timeFromSOR", "TPC n-#sigma(e) vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaEl); hm->AddHistogram(histClass, "TPCnSigPi_pIN", "TPC n-#sigma(#pi) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaPi); - hm->AddHistogram(histClass, "TPCnSigPi_timeFromSOR", "TPC n-#sigma(#pi) vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_timeFromSOR", "TPC n-#sigma(#pi) vs time from SOR", true, 1000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_eta", "TPC n-#sigma(#pi) vs #eta", false, 20, -1.0, 1.0, VarManager::kEta, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_etaPin_prof", " vs (#eta,p_{IN}), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 20, 0.0, 10.0, VarManager::kPin, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_etaCent_prof", " vs (#eta,cent), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 20, 0.0, 100.0, VarManager::kCentFT0C, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_etaContrib_prof", " vs (#eta,n-contrib real), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 20, 0.0, 4000.0, VarManager::kVtxNcontribReal, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_etaZA_prof", " vs (#eta,ZA), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 30, -15.0, 15.0, VarManager::kNTPCpileupZA, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_etaNZA_prof", " vs (#eta,NZA), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 30, 0.0, 1500.0, VarManager::kNTPCpileupContribA, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_centFT0C", "TPC n-#sigma(#pi) vs centrality", false, 20, 0.0, 100.0, VarManager::kCentFT0C, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_itsOccup", "TPC n-#sigma(#pi) vs vtx. contrib real", false, 50, 0.0, 4000.0, VarManager::kVtxNcontribReal, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_pileupZA", "TPC n-#sigma(#pi) vs pileup ZA", false, 60, -15.0, 15.0, VarManager::kNTPCpileupZA, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_pileupZC", "TPC n-#sigma(#pi) vs pileup ZC", false, 60, -15.0, 15.0, VarManager::kNTPCpileupZC, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_pileupNA", "TPC n-#sigma(#pi) vs n.pileup contrib A", false, 60, 0.0, 1500.0, VarManager::kNTPCpileupContribA, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigPi_pileupNC", "TPC n-#sigma(#pi) vs n.pileup contrib C", false, 60, 0.0, 1500.0, VarManager::kNTPCpileupContribC, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi); hm->AddHistogram(histClass, "TPCnSigKa_pIN", "TPC n-#sigma(K) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaKa); hm->AddHistogram(histClass, "TPCnSigPr_pIN", "TPC n-#sigma(p) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaPr); hm->AddHistogram(histClass, "TPCnSigPr_timeFromSOR", "TPC n-#sigma(p) vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaPr); @@ -801,7 +817,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h if (subGroupStr.Contains("pbpb")) { hm->AddHistogram(histClass, "Mass_CentFT0C", "", false, 500, 0.0, 5.0, VarManager::kMass, 20, 0.0, 100.0, VarManager::kCentFT0C); hm->AddHistogram(histClass, "Pt_CentFT0C", "", false, 500, 0.0, 1.5, VarManager::kPt, 20, 0.0, 100.0, VarManager::kCentFT0C); - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C", "", false, 500, 0.0, 5.0, VarManager::kMass, 400, 0.0, 40.0, VarManager::kPt, 20, 0.0, 100.0, VarManager::kCentFT0C); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C", "", false, 500, 0.0, 5.0, VarManager::kMass, 250, 0.0, 10.0, VarManager::kPt, 10, 0.0, 100.0, VarManager::kCentFT0C); } if (subGroupStr.Contains("mult")) { hm->AddHistogram(histClass, "Mass_Pt_MultFV0A", "", false, 200, 0.0, 5.0, VarManager::kMass, 40, 0.0, 40.0, VarManager::kPt, 100, 0.0, 25000.0, VarManager::kMultFV0A); diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index d7cde9afe50..e0a6085f44e 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -913,6 +913,10 @@ class VarManager : public TObject static void FillGlobalMuonRefit(T1 const& muontrack, T2 const& mfttrack, const C& collision, float* values = nullptr); template static void FillPair(T1 const& t1, T2 const& t2, float* values = nullptr); + template + static void FillPairCollision(C const& collision, T1 const& t1, T2 const& t2, float* values = nullptr); + template + static void FillPairCollisionMatCorr(C const& collision, T1 const& t1, T2 const& t2, M const& materialCorr, P const& propagator, float* values = nullptr); template static void FillTriple(T1 const& t1, T2 const& t2, T3 const& t3, float* values = nullptr, PairCandidateType pairType = kTripleCandidateToEEPhoton); template @@ -1467,6 +1471,7 @@ void VarManager::FillEvent(T const& event, float* values) values[kBC] = event.globalBC(); values[kBCOrbit] = event.globalBC() % o2::constants::lhc::LHCMaxBunches; values[kTimestamp] = event.timestamp(); + values[kTimeFromSOR] = (fgSOR > 0 ? (event.timestamp() - fgSOR) / 60000. : -1.0); values[kCentVZERO] = event.centRun2V0M(); values[kCentFT0C] = event.centFT0C(); if (fgUsedVars[kIsNoITSROFBorderRecomputed]) { @@ -1623,6 +1628,14 @@ void VarManager::FillEvent(T const& event, float* values) values[kPsi2ANEG] = Psi2ANEG; values[kPsi2B] = Psi2B; values[kPsi2C] = Psi2C; + + values[kR2SP_AB] = (values[kQ2X0A] * values[kQ2X0B] + values[kQ2Y0A] * values[kQ2Y0B]); + values[kR2SP_AC] = (values[kQ2X0A] * values[kQ2X0C] + values[kQ2Y0A] * values[kQ2Y0C]); + values[kR2SP_BC] = (values[kQ2X0B] * values[kQ2X0C] + values[kQ2Y0B] * values[kQ2Y0C]); + + values[kR2EP_AB] = TMath::Cos(2 * (Psi2A - Psi2B)); + values[kR2EP_AC] = TMath::Cos(2 * (Psi2A - Psi2C)); + values[kR2EP_BC] = TMath::Cos(2 * (Psi2B - Psi2C)); } if constexpr ((fillMap & CollisionMC) > 0) { @@ -2539,6 +2552,116 @@ void VarManager::FillPair(T1 const& t1, T2 const& t2, float* values) } } +template +void VarManager::FillPairCollision(const C& collision, T1 const& t1, T2 const& t2, float* values) +{ + if (!values) { + values = fgValues; + } + + if constexpr ((pairType == kDecayToEE) && ((fillMap & TrackCov) > 0 || (fillMap & ReducedTrackBarrelCov) > 0)) { + + if (fgUsedVars[kQuadDCAabsXY] || fgUsedVars[kQuadDCAsigXY] || fgUsedVars[kQuadDCAabsZ] || fgUsedVars[kQuadDCAsigZ] || fgUsedVars[kQuadDCAsigXYZ] || fgUsedVars[kSignQuadDCAsigXY]) { + + auto trackPart1 = getTrackPar(t1); + std::array dca1{1e10f, 1e10f}; + trackPart1.propagateParamToDCA({collision.posX(), collision.posY(), collision.posZ()}, fgMagField, &dca1); + + auto trackPart2 = getTrackPar(t2); + std::array dca2{1e10f, 1e10f}; + trackPart2.propagateParamToDCA({collision.posX(), collision.posY(), collision.posZ()}, fgMagField, &dca2); + + // Recalculated quantities + double dca1XY = dca1[0]; + double dca2XY = dca2[0]; + double dca1Z = dca1[1]; + double dca2Z = dca2[1]; + double dca1sigXY = dca1XY / std::sqrt(t1.cYY()); + double dca2sigXY = dca2XY / std::sqrt(t2.cYY()); + double dca1sigZ = dca1Z / std::sqrt(t1.cZZ()); + double dca2sigZ = dca2Z / std::sqrt(t2.cZZ()); + + values[kQuadDCAabsXY] = std::sqrt((dca1XY * dca1XY + dca2XY * dca2XY) / 2); + values[kQuadDCAsigXY] = std::sqrt((dca1sigXY * dca1sigXY + dca2sigXY * dca2sigXY) / 2); + values[kQuadDCAabsZ] = std::sqrt((dca1Z * dca1Z + dca2Z * dca2Z) / 2); + values[kQuadDCAsigZ] = std::sqrt((dca1sigZ * dca1sigZ + dca2sigZ * dca2sigZ) / 2); + values[kSignQuadDCAsigXY] = t1.sign() * t2.sign() * TMath::Sign(1., dca1sigXY) * TMath::Sign(1., dca2sigXY) * std::sqrt((dca1sigXY * dca1sigXY + dca2sigXY * dca2sigXY) / 2); + + double det1 = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); + double det2 = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); + if ((det1 < 0) || (det2 < 0)) { + values[kQuadDCAsigXYZ] = -999; + } else { + double chi2t1 = (dca1XY * dca1XY * t1.cZZ() + dca1Z * dca1Z * t1.cYY() - 2. * dca1XY * dca1Z * t1.cZY()) / det1; + double chi2t2 = (dca2XY * dca2XY * t2.cZZ() + dca2Z * dca2Z * t2.cYY() - 2. * dca2XY * dca2Z * t2.cZY()) / det2; + + double dca1sigXYZ = std::sqrt(std::abs(chi2t1) / 2.); + double dca2sigXYZ = std::sqrt(std::abs(chi2t2) / 2.); + + values[kQuadDCAsigXYZ] = std::sqrt((dca1sigXYZ * dca1sigXYZ + dca2sigXYZ * dca2sigXYZ) / 2); + } + } + } +} + +template +void VarManager::FillPairCollisionMatCorr(C const& collision, T1 const& t1, T2 const& t2, M const& materialCorr, P const& propagator, float* values) +{ + if (!values) { + values = fgValues; + } + + if constexpr ((pairType == kDecayToEE) && ((fillMap & TrackCov) > 0 || (fillMap & ReducedTrackBarrelCov) > 0)) { + + if (fgUsedVars[kQuadDCAabsXY] || fgUsedVars[kQuadDCAsigXY] || fgUsedVars[kQuadDCAabsZ] || fgUsedVars[kQuadDCAsigZ] || fgUsedVars[kQuadDCAsigXYZ] || fgUsedVars[kSignQuadDCAsigXY]) { + + auto trackPart1 = getTrackPar(t1); + std::array dca1{1e10f, 1e10f}; + std::array pVect1 = {t1.px(), t1.py(), t1.pz()}; + // trackPar.propagateParamToDCA({collision.posX(), collision.posY(), collision.posZ()}, fgMagField, &dca); + propagator->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPart1, 2.f, materialCorr, &dca1); + getPxPyPz(trackPart1, pVect1); + + auto trackPart2 = getTrackPar(t2); + std::array dca2{1e10f, 1e10f}; + std::array pVect2 = {t2.px(), t2.py(), t2.pz()}; + // trackPar.propagateParamToDCA({collision.posX(), collision.posY(), collision.posZ()}, fgMagField, &dca); + propagator->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPart2, 2.f, materialCorr, &dca2); + getPxPyPz(trackPart2, pVect2); + + // Recalculated quantities + double dca1XY = dca1[0]; + double dca2XY = dca2[0]; + double dca1Z = dca1[1]; + double dca2Z = dca2[1]; + double dca1sigXY = dca1XY / std::sqrt(t1.cYY()); + double dca2sigXY = dca2XY / std::sqrt(t2.cYY()); + double dca1sigZ = dca1Z / std::sqrt(t1.cZZ()); + double dca2sigZ = dca2Z / std::sqrt(t2.cZZ()); + + values[kQuadDCAabsXY] = std::sqrt((dca1XY * dca1XY + dca2XY * dca2XY) / 2); + values[kQuadDCAsigXY] = std::sqrt((dca1sigXY * dca1sigXY + dca2sigXY * dca2sigXY) / 2); + values[kQuadDCAabsZ] = std::sqrt((dca1Z * dca1Z + dca2Z * dca2Z) / 2); + values[kQuadDCAsigZ] = std::sqrt((dca1sigZ * dca1sigZ + dca2sigZ * dca2sigZ) / 2); + values[kSignQuadDCAsigXY] = t1.sign() * t2.sign() * TMath::Sign(1., dca1sigXY) * TMath::Sign(1., dca2sigXY) * std::sqrt((dca1sigXY * dca1sigXY + dca2sigXY * dca2sigXY) / 2); + + double det1 = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); + double det2 = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); + if ((det1 < 0) || (det2 < 0)) { + values[kQuadDCAsigXYZ] = -999; + } else { + double chi2t1 = (dca1XY * dca1XY * t1.cZZ() + dca1Z * dca1Z * t1.cYY() - 2. * dca1XY * dca1Z * t1.cZY()) / det1; + double chi2t2 = (dca2XY * dca2XY * t2.cZZ() + dca2Z * dca2Z * t2.cYY() - 2. * dca2XY * dca2Z * t2.cZY()) / det2; + + double dca1sigXYZ = std::sqrt(std::abs(chi2t1) / 2.); + double dca2sigXYZ = std::sqrt(std::abs(chi2t2) / 2.); + + values[kQuadDCAsigXYZ] = std::sqrt((dca1sigXYZ * dca1sigXYZ + dca2sigXYZ * dca2sigXYZ) / 2); + } + } + } +} + template void VarManager::FillTriple(T1 const& t1, T2 const& t2, T3 const& t3, float* values, PairCandidateType pairType) { diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index 47209e426a1..ba3add306c7 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -809,6 +809,9 @@ DECLARE_SOA_TABLE(DimuonsAll, "AOD", "RTDIMUONALL", //! reducedpair::VertexPz, reducedpair::SVertex); +DECLARE_SOA_TABLE(DileptonsMiniTree, "AOD", "RTDILEPTMTREE", //! + reducedpair::Mass, reducedpair::Pt, reducedpair::Eta, reducedpair::CentFT0C, reducedpair::Cos2DeltaPhi); + using Dielectron = Dielectrons::iterator; using StoredDielectron = StoredDielectrons::iterator; using Dimuon = Dimuons::iterator; @@ -819,6 +822,7 @@ using DileptonFlow = DileptonsFlow::iterator; using DileptonInfo = DileptonsInfo::iterator; using DielectronAll = DielectronsAll::iterator; using DimuonAll = DimuonsAll::iterator; +using DileptonMiniTree = DileptonsMiniTree::iterator; // Tables for using analysis-dilepton-track with analysis-asymmetric-pairing DECLARE_SOA_TABLE(Ditracks, "AOD", "RTDITRACK", //! diff --git a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx index 4f2167ea835..bcb465d13fb 100644 --- a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx @@ -152,10 +152,8 @@ struct TableMakerMC { Configurable fIsRun2{"cfgIsRun2", false, "Whether we analyze Run-2 or Run-3 data"}; Configurable fConfigBarrelTrackMaxAbsEta{"cfgBarrelMaxAbsEta", 0.9f, "Eta absolute value cut for tracks in the barrel"}; Configurable fConfigBarrelTrackMinPt{"cfgBarrelMinPt", 0.5f, "Minimum pt for tracks in the barrel"}; - Configurable fConfigBarrelRequireTPC{"cfgBarrelRequireTPC", true, "Require TPC for tracks in the barrel"}; Configurable fConfigBarrelMinTPCncls{"cfgBarrelMinTPCncls", 50.0f, "Minimum TPC cls for tracks in the barrel"}; Configurable fConfigBarrelMaxTPCchi2{"cfgBarrelMaxTPCchi2", 10.0f, "Maximum TPC chi2/ndf for tracks in the barrel"}; - Configurable fConfigBarrelRequireITS{"cfgBarrelRequireITS", true, "Require ITS for tracks in the barrel"}; Configurable fConfigBarrelMaxITSchi2{"cfgBarrelMaxITSchi2", 36.0f, "Maximum ITS chi2/ndf for tracks in the barrel"}; Configurable fConfigMuonPtLow{"cfgMuonLowPt", 1.0f, "Low pt cut for muons"}; @@ -165,9 +163,14 @@ struct TableMakerMC { Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable grpmagPathRun2{"grpmagPathRun2", "GLO/GRP/GRP", "CCDB path of the GRPObject (Usage for Run 2)"}; + // Track related options + Configurable fPropTrack{"cfgPropTrack", true, "Propagate tracks to primary vertex"}; + // Muon related options Configurable fPropMuon{"cfgPropMuon", true, "Propagate muon tracks through absorber (do not use if applying pairing)"}; Configurable fRefitGlobalMuon{"cfgRefitGlobalMuon", true, "Correct global muon parameters"}; + Configurable fMuonMatchEtaMin{"cfgMuonMatchEtaMin", -4.0f, "Definition of the acceptance of muon tracks to be matched with MFT"}; + Configurable fMuonMatchEtaMax{"cfgMuonMatchEtaMax", -2.5f, "Definition of the acceptance of muon tracks to be matched with MFT"}; Service fCCDB; o2::ccdb::CcdbApi fCCDBApi; @@ -353,9 +356,9 @@ struct TableMakerMC { bool checked = false; if constexpr (soa::is_soa_filtered_v) { auto mctrack_raw = mcTracks.rawIteratorAt(mctrack.globalIndex()); - checked = sig.CheckSignal(false, mctrack_raw); + checked = sig.CheckSignal(true, mctrack_raw); } else { - checked = sig.CheckSignal(false, mctrack); + checked = sig.CheckSignal(true, mctrack); } if (checked) { mcflags |= (uint16_t(1) << i); @@ -517,6 +520,9 @@ struct TableMakerMC { trackFilteringTag = uint64_t(0); trackTempFilterMap = uint8_t(0); VarManager::FillTrack(track); + if (fPropTrack && (track.collisionId() != collision.globalIndex())) { + VarManager::FillTrackCollision(track, collision); + } if (fDoDetailedQA) { fHistMan->FillHistClass("TrackBarrel_BeforeCuts", VarManager::fgValues); } @@ -652,8 +658,8 @@ struct TableMakerMC { } } - template - void skimMuons(TEvent const& collision, TMuons const& muons, FwdTrackAssoc const& muonAssocs, aod::McParticles const& mcTracks, MFTTracks const& /*mftTracks*/) + template + void skimMuons(TEvent const& collision, TMuons const& muons, FwdTrackAssoc const& muonAssocs, aod::McParticles const& mcTracks, TMFTTracks const& /*mftTracks*/) { // Skim the fwd-tracks (muons) // Loop over the collision-track associations, recompute track properties depending on the collision assigned, and apply track cuts for selection @@ -672,6 +678,7 @@ struct TableMakerMC { auto muon = assoc.template fwdtrack_as(); trackFilteringTag = uint8_t(0); + trackTempFilterMap = uint8_t(0); VarManager::FillTrack(muon); // NOTE: If a muon is associated to multiple collisions, depending on the selections, // it may be accepted for some associations and rejected for other @@ -681,6 +688,9 @@ struct TableMakerMC { // recalculte pDca and global muon kinematics if (static_cast(muon.trackType()) < 2 && fRefitGlobalMuon) { auto muontrack = muon.template matchMCHTrack_as(); + if (muontrack.eta() < fMuonMatchEtaMin || muontrack.eta() > fMuonMatchEtaMax) { + continue; + } auto mfttrack = muon.template matchMFTTrack_as(); VarManager::FillTrackCollision(muontrack, collision); VarManager::FillGlobalMuonRefit(muontrack, mfttrack, collision); @@ -909,9 +919,14 @@ struct TableMakerMC { auto groupedMFTIndices = mftAssocs.sliceBy(mfttrackIndicesPerCollision, origIdx); skimMFT(collision, mftTracks, groupedMFTIndices); } - if constexpr (static_cast(TMuonFillMap) && static_cast(TMFTFillMap)) { - auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); - skimMuons(collision, muons, groupedMuonIndices, mcParticles, mftTracks); + if constexpr (static_cast(TMuonFillMap)) { + if constexpr (static_cast(TMFTFillMap)) { + auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); + skimMuons(collision, muons, groupedMuonIndices, mcParticles, mftTracks); + } else { + auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); + skimMuons(collision, muons, groupedMuonIndices, mcParticles, nullptr); + } } } // end loop over skimmed collisions } diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index c8489fe7c53..f7df4a672bc 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -111,7 +111,8 @@ DECLARE_SOA_TABLE(AmbiguousTracksFwd, "AOD", "AMBIGUOUSFWDTR", //! Table for Fwd // constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision; // constexpr static uint32_t gkEventFillMapWithFilter = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::EventFilter; -// constexpr static uint32_t gkEventFillMapWithMult = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult; +constexpr static uint32_t gkEventFillMapWithMults = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult; +constexpr static uint32_t gkEventFillMapWithMultsZdc = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::Zdc; constexpr static uint32_t gkEventFillMapWithMultsAndEventFilter = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::CollisionMultExtra | VarManager::ObjTypes::EventFilter; constexpr static uint32_t gkEventFillMapWithMultsEventFilterZdc = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::EventFilter | VarManager::ObjTypes::Zdc; // constexpr static uint32_t gkEventFillMapWithCent = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionCent; @@ -206,6 +207,8 @@ struct TableMaker { // Muon related options Configurable fPropMuon{"cfgPropMuon", true, "Propagate muon tracks through absorber (do not use if applying pairing)"}; Configurable fRefitGlobalMuon{"cfgRefitGlobalMuon", true, "Correct global muon parameters"}; + Configurable fMuonMatchEtaMin{"cfgMuonMatchEtaMin", -4.0f, "Definition of the acceptance of muon tracks to be matched with MFT"}; + Configurable fMuonMatchEtaMax{"cfgMuonMatchEtaMax", -2.5f, "Definition of the acceptance of muon tracks to be matched with MFT"}; Service fCCDB; @@ -273,9 +276,9 @@ struct TableMaker { histClasses += "Event_AfterCuts;"; } - bool enableBarrelHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterBarrelOnly") || + bool enableBarrelHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterBarrelOnly") || context.mOptions.get("processPPBarrelOnly") || context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbBarrelOnly") || context.mOptions.get("processPbPbBarrelOnlyWithV0Bits")); - bool enableMuonHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterMuonOnly") || context.mOptions.get("processPPWithFilterMuonMFT") || + bool enableMuonHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterMuonOnly") || context.mOptions.get("processPPWithFilterMuonMFT") || context.mOptions.get("processPPMuonOnly") || context.mOptions.get("processPPMuonMFT") || context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbMuonOnly") || context.mOptions.get("processPbPbMuonMFT")); if (enableBarrelHistos) { @@ -522,7 +525,7 @@ struct TableMaker { } } else { if (!fEventCut->IsSelected(VarManager::fgValues)) { - return; + continue; } } @@ -735,8 +738,8 @@ struct TableMaker { } } - template - void skimMuons(TEvent const& collision, TBCs const& /*bcs*/, TMuons const& muons, FwdTrackAssoc const& muonAssocs, MFTTracks const& /*mftTracks*/) + template + void skimMuons(TEvent const& collision, TBCs const& /*bcs*/, TMuons const& muons, FwdTrackAssoc const& muonAssocs, TMFTTracks const& /*mftTracks*/) { // Skim the fwd-tracks (muons) // Loop over the collision-track associations, recompute track properties depending on the collision assigned, and apply track cuts for selection @@ -754,6 +757,7 @@ struct TableMaker { auto muon = assoc.template fwdtrack_as(); trackFilteringTag = uint8_t(0); + trackTempFilterMap = uint8_t(0); VarManager::FillTrack(muon); // NOTE: If a muon is associated to multiple collisions, depending on the selections, // it may be accepted for some associations and rejected for other @@ -763,6 +767,9 @@ struct TableMaker { // recalculte pDca and global muon kinematics if (static_cast(muon.trackType()) < 2 && fRefitGlobalMuon) { auto muontrack = muon.template matchMCHTrack_as(); + if (muontrack.eta() < fMuonMatchEtaMin || muontrack.eta() > fMuonMatchEtaMax) { + continue; + } auto mfttrack = muon.template matchMFTTrack_as(); VarManager::FillTrackCollision(muontrack, collision); VarManager::FillGlobalMuonRefit(muontrack, mfttrack, collision); @@ -904,6 +911,10 @@ struct TableMaker { } // skim collisions + event.reserve(collisions.size()); + eventExtended.reserve(collisions.size()); + eventVtxCov.reserve(collisions.size()); + skimCollisions(collisions, bcs, zdcs, trackAssocs, tracksBarrel); if (fCollIndexMap.size() == 0) { return; @@ -948,9 +959,14 @@ struct TableMaker { auto groupedMFTIndices = mftAssocs.sliceBy(mfttrackIndicesPerCollision, origIdx); skimMFT(collision, bcs, mftTracks, groupedMFTIndices); } - if constexpr (static_cast(TMuonFillMap) && static_cast(TMFTFillMap)) { - auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); - skimMuons(collision, bcs, muons, groupedMuonIndices, mftTracks); + if constexpr (static_cast(TMuonFillMap)) { + if constexpr (static_cast(TMFTFillMap)) { + auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); + skimMuons(collision, bcs, muons, groupedMuonIndices, mftTracks); + } else { + auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); + skimMuons(collision, bcs, muons, groupedMuonIndices, nullptr); + } } } // end loop over skimmed collisions } @@ -992,6 +1008,29 @@ struct TableMaker { fullSkimming(collisions, bcs, nullptr, nullptr, muons, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); } + // produce the barrel-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data + void processPPBarrelOnly(MyEventsWithMults const& collisions, MyBCs const& bcs, aod::Zdcs& zdcs, + MyBarrelTracksWithCov const& tracksBarrel, + TrackAssoc const& trackAssocs) + { + fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + } + + // produce the muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data + void processPPMuonOnly(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs, MFTTracks const& mftTracks) + { + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr); + } + + // produce the muon+mft DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data + void processPPMuonMFT(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + MyMuonsWithCov const& muons, MFTTracks const& mftTracks, + FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) + { + fullSkimming(collisions, bcs, nullptr, nullptr, muons, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); + } + // produce the full DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter void processPbPb(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, MyBarrelTracksWithCov const& tracksBarrel, @@ -1048,6 +1087,9 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processPPWithFilterBarrelOnly, "Build barrel only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb, w/ event filtering", false); PROCESS_SWITCH(TableMaker, processPPWithFilterMuonOnly, "Build muon only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb, w/ event filtering", false); PROCESS_SWITCH(TableMaker, processPPWithFilterMuonMFT, "Build muon + mft DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb, w/ event filtering", false); + PROCESS_SWITCH(TableMaker, processPPBarrelOnly, "Build barrel only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); + PROCESS_SWITCH(TableMaker, processPPMuonOnly, "Build muon only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); + PROCESS_SWITCH(TableMaker, processPPMuonMFT, "Build muon + mft DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); PROCESS_SWITCH(TableMaker, processPbPb, "Build full DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbBarrelOnly, "Build barrel only DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbBarrelOnlyWithV0Bits, "Build barrel only DQ skimmed data model typically for Pb-Pb, w/ V0 bits, w/o event filtering", false); diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index b288c1f3974..7c1a51ddbc0 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -506,7 +506,7 @@ struct AnalysisTrackSelection { if (filterMap > 0) { for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) { if (track.has_reducedMCTrack()) { - if ((*sig).CheckSignal(false, track.reducedMCTrack())) { + if ((*sig).CheckSignal(true, track.reducedMCTrack())) { mcDecision |= (uint32_t(1) << isig); } } @@ -774,7 +774,7 @@ struct AnalysisMuonSelection { for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) { if constexpr ((TMuonFillMap & VarManager::ObjTypes::ReducedMuon) > 0) { if (track.has_reducedMCTrack()) { - if ((*sig).CheckSignal(false, track.reducedMCTrack())) { + if ((*sig).CheckSignal(true, track.reducedMCTrack())) { mcDecision |= (uint32_t(1) << isig); } } @@ -874,6 +874,8 @@ struct AnalysisPrefilterSelection { Configurable fConfigPrefilterTrackCut{"cfgPrefilterTrackCut", "", "Prefilter track cut"}; Configurable fConfigPrefilterPairCut{"cfgPrefilterPairCut", "", "Prefilter pair cut"}; Configurable fConfigTrackCuts{"cfgTrackCuts", "", "Track cuts for which to run the prefilter"}; + // Track related options + Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; std::map fPrefilterMap; AnalysisCompositeCut* fPairCut; @@ -938,8 +940,8 @@ struct AnalysisPrefilterSelection { VarManager::SetupTwoProngFwdDCAFitter(5.0f, true, 200.0f, 1.0e-3f, 0.9f, true); } - template - void runPrefilter(soa::Join const& assocs, TTracks const& /*tracks*/) + template + void runPrefilter(TEvent const& event, soa::Join const& assocs, TTracks const& /*tracks*/) { for (auto& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) { @@ -964,6 +966,9 @@ struct AnalysisPrefilterSelection { // compute pair quantities VarManager::FillPair(track1, track2); + if (fPropTrack) { + VarManager::FillPairCollision(event, track1, track2); + } // if the pair fullfils the criteria, add an entry into the prefilter map for the two tracks if (fPairCut->IsSelected(VarManager::fgValues)) { if (fPrefilterMap.find(track1.globalIndex()) == fPrefilterMap.end() && track1Candidate > 0) { @@ -984,7 +989,7 @@ struct AnalysisPrefilterSelection { for (auto& event : events) { auto groupedAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); if (groupedAssocs.size() > 1) { - runPrefilter(groupedAssocs, tracks); + runPrefilter(event, groupedAssocs, tracks); } } uint32_t mymap = -1; @@ -1056,6 +1061,9 @@ struct AnalysisSameEventPairing { Configurable fConfigMCGenSignals{"cfgBarrelMCGenSignals", "", "Comma separated list of MC signals (generated)"}; Configurable fConfigSkimSignalOnly{"fConfigSkimSignalOnly", false, "Configurable to select only matched candidates"}; + // Track related options + Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; + Service fCCDB; // Filter filterEventSelected = aod::dqanalysisflags::isEventSelected & uint32_t(1); @@ -1431,7 +1439,7 @@ struct AnalysisSameEventPairing { mcDecision = 0; for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { - if ((*sig).CheckSignal(false, t1.reducedMCTrack(), t2.reducedMCTrack())) { + if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) { mcDecision |= (uint32_t(1) << isig); } } @@ -1442,6 +1450,9 @@ struct AnalysisSameEventPairing { } VarManager::FillPair(t1, t2); + if (fPropTrack) { + VarManager::FillPairCollision(event, t1, t2); + } if constexpr (TTwoProngFitter) { VarManager::FillPairVertexing(event, t1, t2, fConfigPropToPCA); } @@ -1478,7 +1489,7 @@ struct AnalysisSameEventPairing { mcDecision = 0; for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { - if ((*sig).CheckSignal(false, t1.reducedMCTrack(), t2.reducedMCTrack())) { + if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) { mcDecision |= (uint32_t(1) << isig); } } @@ -1490,6 +1501,9 @@ struct AnalysisSameEventPairing { } VarManager::FillPair(t1, t2); + if (fPropTrack) { + VarManager::FillPairCollision(event, t1, t2); + } if constexpr (TTwoProngFitter) { VarManager::FillPairVertexing(event, t1, t2, fConfigPropToPCA); } @@ -1637,9 +1651,9 @@ struct AnalysisSameEventPairing { bool checked = false; /*if constexpr (soa::is_soa_filtered_v) { auto mctrack_raw = groupedMCTracks.rawIteratorAt(mctrack.globalIndex()); - checked = sig.CheckSignal(false, mctrack_raw); + checked = sig.CheckSignal(true, mctrack_raw); } else {*/ - checked = sig.CheckSignal(false, mctrack); + checked = sig.CheckSignal(true, mctrack); //} if (checked) { fHistMan->FillHistClass(Form("MCTruthGen_%s", sig.GetName()), VarManager::fgValues); @@ -1658,7 +1672,7 @@ struct AnalysisSameEventPairing { if (sig.GetNProngs() != 2) { // NOTE: 2-prong signals required here continue; } - if (sig.CheckSignal(false, t1_raw, t2_raw)) { + if (sig.CheckSignal(true, t1_raw, t2_raw)) { VarManager::FillPairMC(t1, t2); fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig.GetName()), VarManager::fgValues); } @@ -1947,7 +1961,7 @@ struct AnalysisDileptonTrack { mcDecision = 0; isig = 0; for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { - if ((*sig).CheckSignal(false, lepton1MC, lepton2MC, trackMC)) { + if ((*sig).CheckSignal(true, lepton1MC, lepton2MC, trackMC)) { mcDecision |= (uint32_t(1) << isig); } } @@ -1968,7 +1982,7 @@ struct AnalysisDileptonTrack { mcDecision = 0; isig = 0; for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { - if ((*sig).CheckSignal(false, lepton1MC, lepton2MC, trackMC)) { + if ((*sig).CheckSignal(true, lepton1MC, lepton2MC, trackMC)) { mcDecision |= (uint32_t(1) << isig); } } @@ -2056,7 +2070,7 @@ struct AnalysisDileptonTrack { // TODO: Use the mcReducedFlags to select signals isig = 0; for (auto& sig : fGenMCSignals) { - if (sig.CheckSignal(false, track)) { + if (sig.CheckSignal(true, track)) { fHistMan->FillHistClass(fHistNamesMCgen[isig++], VarManager::fgValues); } } diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 572eb46f38f..34435873ff6 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -918,6 +918,7 @@ struct AnalysisSameEventPairing { Produces dimuonAllList; Produces dileptonFlowList; Produces dileptonInfoList; + Produces dileptonMiniTree; float mMagField = 0.0; o2::parameters::GRPMagField* grpmag = nullptr; o2::base::MatLayerCylSet* lut = nullptr; @@ -948,6 +949,13 @@ struct AnalysisSameEventPairing { Configurable fCollisionSystem{"syst", "pp", "Collision system, pp or PbPb"}; Configurable fCenterMassEnergy{"energy", 13600, "Center of mass energy in GeV"}; + // Configurables to create output tree (flat tables or minitree) + struct : ConfigurableGroup { + Configurable fConfigMiniTree{"useMiniTree.cfgMiniTree", false, "Produce a single flat table with minimal information for analysis"}; + Configurable fConfigMiniTreeMinMass{"useMiniTree.cfgMiniTreeMinMass", 2, "Min. mass cut for minitree"}; + Configurable fConfigMiniTreeMaxMass{"useMiniTree.cfgMiniTreeMaxMass", 5, "Max. mass cut for minitree"}; + } useMiniTree; + Service ccdb; Filter filterEventSelected = aod::dqanalysisflags::isEventSelected == 1; // NOTE: the barrel filter map contains decisions for both electrons and hadrons used in the correlation task @@ -1180,6 +1188,9 @@ struct AnalysisSameEventPairing { dielectronAllList.reserve(1); dimuonAllList.reserve(1); } + if (useMiniTree.fConfigMiniTree) { + dileptonMiniTree.reserve(1); + } if (fConfigMultDimuons.value) { @@ -1318,6 +1329,16 @@ struct AnalysisSameEventPairing { if (fConfigAmbiguousHist && !(t1.isAmbiguous() || t2.isAmbiguous())) { fHistMan->FillHistClass(Form("%s_unambiguous", histNames[iCut][0].Data()), VarManager::fgValues); } + if (useMiniTree.fConfigMiniTree) { + float dileptonMass = VarManager::fgValues[VarManager::kMass]; + if (dileptonMass > useMiniTree.fConfigMiniTreeMinMass && dileptonMass < useMiniTree.fConfigMiniTreeMaxMass) { + dileptonMiniTree(VarManager::fgValues[VarManager::kMass], + VarManager::fgValues[VarManager::kPt], + VarManager::fgValues[VarManager::kRap], + VarManager::fgValues[VarManager::kCentFT0C], + VarManager::fgValues[VarManager::kCos2DeltaPhi]); + } + } } else { if (t1.sign() > 0) { fHistMan->FillHistClass(histNames[iCut][1].Data(), VarManager::fgValues); diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index 1fe6175fca1..f16d172f0ce 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -98,8 +98,10 @@ DECLARE_SOA_TABLE(BmesonCandidates, "AOD", "DQBMESONS", dqanalysisflags::massBca // Declarations of various short names using MyEvents = soa::Join; +using MyEventsMultExtra = soa::Join; using MyEventsZdc = soa::Join; using MyEventsSelected = soa::Join; +using MyEventsMultExtraSelected = soa::Join; using MyEventsHashSelected = soa::Join; using MyEventsVtxCov = soa::Join; using MyEventsVtxCovSelected = soa::Join; @@ -126,6 +128,7 @@ constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::ReducedEvent | constexpr static uint32_t gkEventFillMapWithZdc = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedZdc; constexpr static uint32_t gkEventFillMapWithCov = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov; constexpr static uint32_t gkEventFillMapWithCovZdc = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov | VarManager::ReducedZdc; +constexpr static uint32_t gkEventFillMapWithMultExtra = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventMultExtra; // constexpr static uint32_t gkEventFillMapWithQvector = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventQvector; // constexpr static uint32_t gkEventFillMapWithCovQvector = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov | VarManager::ObjTypes::ReducedEventQvector; constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::ReducedTrackBarrel | VarManager::ObjTypes::ReducedTrackBarrelPID; @@ -174,7 +177,6 @@ struct AnalysisEventSelection { std::map fSelMap; // key: reduced event global index, value: event selection decision std::map> fBCCollMap; // key: global BC, value: vector of reduced event global indices - std::map fMetadataRCT, fHeader; int fCurrentRun; void init(o2::framework::InitContext&) @@ -214,18 +216,20 @@ struct AnalysisEventSelection { void runEventSelection(TEvents const& events) { if (events.size() > 0 && events.begin().runNumber() != fCurrentRun) { - fHeader = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), fMetadataRCT, -1); - uint64_t sor = std::atol(fHeader["SOR"].c_str()); - uint64_t eor = std::atol(fHeader["EOR"].c_str()); - LOGP(debug, "=========================== SOR / EOR is {} / {}", sor, eor); - // cout << "=========================== SOR / EOR is " << sor << " / " << eor << endl; + std::map metadataRCT, header; + header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), metadataRCT, -1); + uint64_t sor = std::atol(header["SOR"].c_str()); + uint64_t eor = std::atol(header["EOR"].c_str()); + VarManager::SetSORandEOR(sor, eor); + LOG(info) << "============================= SOR / EOR :: " << sor << " / " << eor; + auto alppar = fCCDB->getForTimeStamp>("ITS/Config/AlpideParam", events.begin().timestamp()); EventSelectionParams* par = fCCDB->getForTimeStamp("EventSelection/EventSelectionParams", events.begin().timestamp()); int itsROFrameStartBorderMargin = fConfigITSROFrameStartBorderMargin < 0 ? par->fITSROFrameStartBorderMargin : fConfigITSROFrameStartBorderMargin; int itsROFrameEndBorderMargin = fConfigITSROFrameEndBorderMargin < 0 ? par->fITSROFrameEndBorderMargin : fConfigITSROFrameEndBorderMargin; VarManager::SetITSROFBorderselection(alppar->roFrameBiasInBC, alppar->roFrameLengthInBC, itsROFrameStartBorderMargin, itsROFrameEndBorderMargin); LOGP(debug, "==============++++++++++++========== roBias / roLength / start / end :: {} / {} / {} / {}", alppar->roFrameBiasInBC, alppar->roFrameLengthInBC, itsROFrameStartBorderMargin, itsROFrameEndBorderMargin); - // cout << "==============++++++++++++========== roBias / roLength / start / end :: " << alppar->roFrameBiasInBC << " / " << alppar->roFrameLengthInBC << " / " << itsROFrameStartBorderMargin << " / " << itsROFrameEndBorderMargin << endl; + fCurrentRun = events.begin().runNumber(); } @@ -320,6 +324,11 @@ struct AnalysisEventSelection { runEventSelection(events); publishSelections(events); } + void processSkimmedWithMultExtra(MyEventsMultExtra const& events) + { + runEventSelection(events); + publishSelections(events); + } void processDummy(MyEvents&) { // do nothing @@ -327,6 +336,7 @@ struct AnalysisEventSelection { PROCESS_SWITCH(AnalysisEventSelection, processSkimmed, "Run event selection on DQ skimmed events", false); PROCESS_SWITCH(AnalysisEventSelection, processSkimmedWithZdc, "Run event selection on DQ skimmed events, with ZDC", false); + PROCESS_SWITCH(AnalysisEventSelection, processSkimmedWithMultExtra, "Run event selection on DQ skimmed events, with mult extra", false); PROCESS_SWITCH(AnalysisEventSelection, processDummy, "Dummy function", false); }; @@ -351,6 +361,7 @@ struct AnalysisTrackSelection { Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; Service fCCDB; + o2::ccdb::CcdbApi fCCDBApi; HistogramManager* fHistMan; std::vector fTrackCuts; @@ -400,6 +411,7 @@ struct AnalysisTrackSelection { fCCDB->setLocalObjectValidityChecking(); fCCDB->setCreatedNotAfter(fConfigNoLaterThan.value); } + fCCDBApi.init(fConfigCcdbUrl.value); } template @@ -408,14 +420,16 @@ struct AnalysisTrackSelection { fNAssocsInBunch.clear(); fNAssocsOutOfBunch.clear(); - if (fConfigComputeTPCpostCalib && events.size() > 0 && fCurrentRun != events.begin().runNumber()) { - auto calibList = fCCDB->getForTimeStamp(fConfigCcdbPathTPC.value, events.begin().timestamp()); - VarManager::SetCalibrationObject(VarManager::kTPCElectronMean, calibList->FindObject("mean_map_electron")); - VarManager::SetCalibrationObject(VarManager::kTPCElectronSigma, calibList->FindObject("sigma_map_electron")); - VarManager::SetCalibrationObject(VarManager::kTPCPionMean, calibList->FindObject("mean_map_pion")); - 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 (events.size() > 0 && fCurrentRun != events.begin().runNumber()) { + if (fConfigComputeTPCpostCalib) { + auto calibList = fCCDB->getForTimeStamp(fConfigCcdbPathTPC.value, events.begin().timestamp()); + VarManager::SetCalibrationObject(VarManager::kTPCElectronMean, calibList->FindObject("mean_map_electron")); + VarManager::SetCalibrationObject(VarManager::kTPCElectronSigma, calibList->FindObject("sigma_map_electron")); + VarManager::SetCalibrationObject(VarManager::kTPCPionMean, calibList->FindObject("mean_map_pion")); + 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")); + } o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); if (grpmag != nullptr) { @@ -424,6 +438,12 @@ struct AnalysisTrackSelection { LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", events.begin().timestamp()); } + std::map metadataRCT, header; + header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), metadataRCT, -1); + uint64_t sor = std::atol(header["SOR"].c_str()); + uint64_t eor = std::atol(header["EOR"].c_str()); + VarManager::SetSORandEOR(sor, eor); + fCurrentRun = events.begin().runNumber(); } @@ -528,6 +548,10 @@ struct AnalysisTrackSelection { { runTrackSelection(assocs, events, tracks); } + void processSkimmedWithMultExtra(ReducedTracksAssoc const& assocs, MyEventsMultExtraSelected const& events, MyBarrelTracks const& tracks) + { + runTrackSelection(assocs, events, tracks); + } void processSkimmedWithCov(ReducedTracksAssoc const& assocs, MyEventsVtxCovSelected const& events, MyBarrelTracksWithCov const& tracks) { runTrackSelection(assocs, events, tracks); @@ -538,6 +562,7 @@ struct AnalysisTrackSelection { } PROCESS_SWITCH(AnalysisTrackSelection, processSkimmed, "Run barrel track selection on DQ skimmed track associations", false); + PROCESS_SWITCH(AnalysisTrackSelection, processSkimmedWithMultExtra, "Run barrel track selection on DQ skimmed track associations, with extra multiplicity tables", false); PROCESS_SWITCH(AnalysisTrackSelection, processSkimmedWithCov, "Run barrel track selection on DQ skimmed tracks w/ cov matrix associations", false); PROCESS_SWITCH(AnalysisTrackSelection, processDummy, "Dummy function", false); }; @@ -907,7 +932,7 @@ struct AnalysisSameEventPairing { Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; Configurable fConfigMixingDepth{"cfgMixingDepth", 100, "Number of Events stored for event mixing"}; - Configurable fConfigAddEventMixingHistogram{"cfgAddEventMixingHistogram", "", "Comma separated list of histograms"}; + // Configurable fConfigAddEventMixingHistogram{"cfgAddEventMixingHistogram", "", "Comma separated list of histograms"}; Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigCcdbPath{"ccdb-path", "Users/lm", "base path to the ccdb object"}; @@ -927,8 +952,11 @@ struct AnalysisSameEventPairing { Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable fConfigCollisionSystem{"syst", "pp", "Collision system, pp or PbPb"}; Configurable fConfigCenterMassEnergy{"energy", 13600, "Center of mass energy in GeV"}; + // Track related options + Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; Service fCCDB; + o2::ccdb::CcdbApi fCCDBApi; Filter filterEventSelected = aod::dqanalysisflags::isEventSelected == uint32_t(1); @@ -958,7 +986,7 @@ struct AnalysisSameEventPairing { void init(o2::framework::InitContext& context) { - fEnableBarrelHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processBarrelOnlySkimmed") || context.mOptions.get("processBarrelOnlyWithCollSkimmed"); + fEnableBarrelHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processBarrelOnlySkimmed") || context.mOptions.get("processBarrelOnlyWithCollSkimmed") || context.mOptions.get("processBarrelOnlySkimmedNoCov"); fEnableBarrelMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingBarrelSkimmed"); fEnableMuonHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processMuonOnlySkimmed"); fEnableMuonMixingHistos = context.mOptions.get("processMixingAllSkimmed"); @@ -1105,6 +1133,7 @@ struct AnalysisSameEventPairing { fCCDB->setURL(fConfigCcdbUrl.value); fCCDB->setCaching(true); fCCDB->setLocalObjectValidityChecking(); + fCCDBApi.init(fConfigCcdbUrl.value); if (fConfigNoCorr) { VarManager::SetupFwdDCAFitterNoCorr(); @@ -1162,7 +1191,7 @@ struct AnalysisSameEventPairing { fOutputList.setObject(fHistMan->GetMainHistogramList()); } - void initParamsFromCCDB(uint64_t timestamp, bool withTwoProngFitter = true) + void initParamsFromCCDB(uint64_t timestamp, int runNumber, bool withTwoProngFitter = true) { if (fConfigUseRemoteField.value) { @@ -1195,6 +1224,12 @@ struct AnalysisSameEventPairing { VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigUseAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations } } + + std::map metadataRCT, header; + header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", runNumber), metadataRCT, -1); + uint64_t sor = std::atol(header["SOR"].c_str()); + uint64_t eor = std::atol(header["EOR"].c_str()); + VarManager::SetSORandEOR(sor, eor); } // Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon) @@ -1203,7 +1238,7 @@ struct AnalysisSameEventPairing { { if (events.size() > 0) { // Additional protection to avoid crashing of events.begin().runNumber() if (fCurrentRun != events.begin().runNumber()) { - initParamsFromCCDB(events.begin().timestamp(), TTwoProngFitter); + initParamsFromCCDB(events.begin().timestamp(), events.begin().runNumber(), TTwoProngFitter); fCurrentRun = events.begin().runNumber(); } } @@ -1290,6 +1325,10 @@ struct AnalysisSameEventPairing { } VarManager::FillPair(t1, t2); + // compute quantities which depend on the associated collision, such as DCA + if (fPropTrack) { + VarManager::FillPairCollision(event, t1, t2); + } if constexpr (TTwoProngFitter) { VarManager::FillPairVertexing(event, t1, t2, fConfigPropToPCA); } @@ -1351,6 +1390,10 @@ struct AnalysisSameEventPairing { } VarManager::FillPair(t1, t2); + // compute quantities which depend on the associated collision, such as DCA + if (fPropTrack) { + VarManager::FillPairCollision(event, t1, t2); + } if constexpr (TTwoProngFitter) { VarManager::FillPairVertexing(event, t1, t2, fConfigPropToPCA); } @@ -1571,6 +1614,13 @@ struct AnalysisSameEventPairing { runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks); } + void processBarrelOnlySkimmedNoCov(MyEventsSelected const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithAmbiguities const& barrelTracks) + { + runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks); + } + void processBarrelOnlyWithCollSkimmed(MyEventsVtxCovSelected const& events, soa::Join const& barrelAssocs, MyBarrelTracksWithCovWithAmbiguitiesWithColl const& barrelTracks) @@ -1606,6 +1656,7 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processAllSkimmed, "Run all types of pairing, with skimmed tracks/muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmed, "Run barrel only pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlyWithCollSkimmed, "Run barrel only pairing, with skimmed tracks and with collision information", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmedNoCov, "Run barrel only pairing (no covariances), with skimmed tracks and with collision information", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMuonOnlySkimmed, "Run muon only pairing, with skimmed tracks", false); 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); diff --git a/PWGEM/Dilepton/Core/DielectronCut.cxx b/PWGEM/Dilepton/Core/DielectronCut.cxx index 8516f174ca9..0beed07efb2 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.cxx +++ b/PWGEM/Dilepton/Core/DielectronCut.cxx @@ -233,6 +233,11 @@ void DielectronCut::SetMaxPinMuonTPConly(float max) mMaxPinMuonTPConly = max; LOG(info) << "Dielectron Cut, set max pin for Muon ID with TPC only: " << mMaxPinMuonTPConly; } +void DielectronCut::SetMaxPinForPionRejectionTPC(float max) +{ + mMaxPinForPionRejectionTPC = max; + LOG(info) << "Dielectron Cut, set max pin for pion rejection in TPC: " << mMaxPinForPionRejectionTPC; +} void DielectronCut::RequireITSibAny(bool flag) { mRequireITSibAny = flag; diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index ff7155b778a..e09fd72fc17 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -200,10 +200,10 @@ class DielectronCut : public TNamed return false; } - // TOF beta cut - if (track.hasTOF() && (track.beta() < mMinTOFbeta || mMaxTOFbeta < track.beta())) { - return false; - } + // // TOF beta cut + // if (track.hasTOF() && (track.beta() < mMinTOFbeta || mMaxTOFbeta < track.beta())) { + // return false; + // } // PID cuts if constexpr (isML) { @@ -271,7 +271,7 @@ class DielectronCut : public TNamed bool PassTOFreq(T const& track) const { bool is_el_included_TPC = mMinTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; - bool is_pi_excluded_TPC = track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi(); + bool is_pi_excluded_TPC = track.tpcInnerParam() < mMaxPinForPionRejectionTPC ? (track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi()) : true; bool is_el_included_TOF = mMinTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < mMaxTOFNsigmaEl; return is_el_included_TPC && is_pi_excluded_TPC && is_el_included_TOF; } @@ -281,10 +281,11 @@ class DielectronCut : public TNamed { bool is_el_included_TPC = mMinTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; bool is_mu_excluded_TPC = mMuonExclusionTPC ? track.tpcNSigmaMu() < mMinTPCNsigmaMu || mMaxTPCNsigmaMu < track.tpcNSigmaMu() : true; - bool is_pi_excluded_TPC = track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi(); + bool is_pi_excluded_TPC = track.tpcInnerParam() < mMaxPinForPionRejectionTPC ? (track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi()) : true; bool is_ka_excluded_TPC = track.tpcNSigmaKa() < mMinTPCNsigmaKa || mMaxTPCNsigmaKa < track.tpcNSigmaKa(); bool is_pr_excluded_TPC = track.tpcNSigmaPr() < mMinTPCNsigmaPr || mMaxTPCNsigmaPr < track.tpcNSigmaPr(); - return is_el_included_TPC && is_mu_excluded_TPC && is_pi_excluded_TPC && is_ka_excluded_TPC && is_pr_excluded_TPC; + bool is_el_included_TOF = track.hasTOF() ? (mMinTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < mMaxTOFNsigmaEl) : true; + return is_el_included_TPC && is_mu_excluded_TPC && is_pi_excluded_TPC && is_ka_excluded_TPC && is_pr_excluded_TPC && is_el_included_TOF; } template @@ -298,7 +299,7 @@ class DielectronCut : public TNamed bool PassTOFif(T const& track) const { bool is_el_included_TPC = mMinTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; - bool is_pi_excluded_TPC = track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi(); + bool is_pi_excluded_TPC = track.tpcInnerParam() < mMaxPinForPionRejectionTPC ? (track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi()) : true; bool is_el_included_TOF = track.hasTOF() ? (mMinTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < mMaxTOFNsigmaEl) : true; return is_el_included_TPC && is_pi_excluded_TPC && is_el_included_TOF; } @@ -384,6 +385,7 @@ class DielectronCut : public TNamed void SetTOFNsigmaKaRange(float min = -1e+10, float max = 1e+10); void SetTOFNsigmaPrRange(float min = -1e+10, float max = 1e+10); void SetMaxPinMuonTPConly(float max); + void SetMaxPinForPionRejectionTPC(float max); void RequireITSibAny(bool flag); void RequireITSib1st(bool flag); @@ -429,6 +431,7 @@ class DielectronCut : public TNamed 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 mMaxPinForPionRejectionTPC{1e10f}; // max pin cut for muon ID with TPConly bool mRequireITSibAny{true}; bool mRequireITSib1st{false}; diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index 1acf3739ae6..9bd0c72b637 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -94,8 +94,9 @@ struct Dilepton { Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - Configurable spresoPath{"spresoPath", "Users/d/dsekihat/PWGEM/dilepton/Qvector/resolution/LHC23zzh/pass3/test", "Path of SP resolution file"}; Configurable cfgApplySPresolution{"cfgApplySPresolution", false, "flag to apply resolution correction for flow analysis"}; + 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 cfgEP2Estimator_for_Mix{"cfgEP2Estimator_for_Mix", 3, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; @@ -166,8 +167,6 @@ struct Dilepton { 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_TOFbeta{"cfg_min_TOFbeta", 0.985, "min TOF beta for single track"}; //|beta - 1 | < 0.015 corresponds to 3 sigma in pp - Configurable cfg_max_TOFbeta{"cfg_max_TOFbeta", 1.015, "max TOF beta for single track"}; //|beta - 1 | < 0.015 corresponds to 3 sigma in pp Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -247,7 +246,7 @@ struct Dilepton { float beamE2 = 0.f; // beam energy float beamP1 = 0.f; // beam momentum float beamP2 = 0.f; // beam momentum - TH1D* h1sp_resolution = nullptr; + TH2D* h2sp_resolution = nullptr; void init(InitContext& /*context*/) { @@ -426,9 +425,9 @@ struct Dilepton { } if (cfgApplySPresolution) { - auto list = ccdb->getForTimeStamp(spresoPath, 10); - h1sp_resolution = reinterpret_cast(list->FindObject("histo_SP_R2_FT0M_BPos_BNeg")); - LOGF(info, "h1sp_resolution.GetBinContent(40) = %f", h1sp_resolution->GetBinContent(40)); + auto list = ccdb->getForTimeStamp(spresoPath, collision.timestamp()); + h2sp_resolution = reinterpret_cast(list->FindObject(spresoHistName.value.data())); + LOGF(info, "h2sp_resolution.GetBinContent(40, 1) = %f", h2sp_resolution->GetBinContent(40, 1)); } } @@ -440,6 +439,7 @@ struct Dilepton { emh_neg = 0x0; map_mixed_eventId_to_centrality.clear(); + map_mixed_eventId_to_occupancy.clear(); map_mixed_eventId_to_qvector.clear(); map_mixed_eventId_to_globalBC.clear(); @@ -449,7 +449,7 @@ struct Dilepton { if (eid_bdt) { delete eid_bdt; } - delete h1sp_resolution; + delete h2sp_resolution; } void addhistograms() @@ -630,7 +630,6 @@ struct Dilepton { fDielectronCut.SetMaxDcaZ(dielectroncuts.cfg_max_dcaz); // for eID - fDielectronCut.SetTOFbetaRange(dielectroncuts.cfg_min_TOFbeta, dielectroncuts.cfg_max_TOFbeta); fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); @@ -687,7 +686,7 @@ struct Dilepton { { bool is_good = true; for (auto& qn : qvectors[nmod]) { - if (abs(qn[0]) > 10.f || abs(qn[1]) > 10.f) { + if (fabs(qn[0]) > 20.f || fabs(qn[1]) > 20.f) { is_good = false; break; } @@ -695,12 +694,28 @@ struct Dilepton { return is_good; } - float getSPresolution(const float centrality) + float getSPresolution(const float centrality, const int occupancy) { - if (h1sp_resolution == nullptr) { + if (h2sp_resolution == nullptr) { return 1.f; } else { - return h1sp_resolution->GetBinContent(h1sp_resolution->FindBin(centrality)); + int binId_cen = h2sp_resolution->GetXaxis()->FindBin(centrality); + int binId_occ = h2sp_resolution->GetYaxis()->FindBin(occupancy); + + if (centrality < h2sp_resolution->GetXaxis()->GetXmin()) { + binId_cen = 1; + } + if (h2sp_resolution->GetXaxis()->GetXmax() < centrality) { + binId_cen = h2sp_resolution->GetXaxis()->GetNbins(); + } + + if (occupancy < h2sp_resolution->GetYaxis()->GetXmin()) { + binId_occ = 1; + } + if (h2sp_resolution->GetYaxis()->GetXmax() < occupancy) { + binId_occ = h2sp_resolution->GetYaxis()->GetNbins(); + } + return h2sp_resolution->GetBinContent(binId_cen, binId_occ); } } @@ -852,9 +867,9 @@ struct Dilepton { }; if constexpr (ev_id == 0) { - // LOGF(info, "collision.centFT0C() = %f, getSPresolution = %f", collision.centFT0C(), getSPresolution(collision.centFT0C())); + // LOGF(info, "collision.centFT0C() = %f, collision.trackOccupancyInTimeRange() = %d, getSPresolution = %f", collision.centFT0C(), collision.trackOccupancyInTimeRange(), getSPresolution(collision.centFT0C(), collision.trackOccupancyInTimeRange())); - 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()); + 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, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hPrfUQ"), v12.M(), v12.Pt(), pair_dca, sp, weight); @@ -1003,7 +1018,7 @@ struct Dilepton { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi) && ((dielectroncuts.cfg_min_TOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < dielectroncuts.cfg_max_TOFbeta) || o2::aod::pidtofbeta::beta < 0.f); + Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Partition positive_electrons = o2::aod::emprimaryelectron::sign > int8_t(0); Partition negative_electrons = o2::aod::emprimaryelectron::sign < int8_t(0); @@ -1018,6 +1033,7 @@ struct Dilepton { TEMH* emh_neg = nullptr; std::map, std::vector>>> map_mixed_eventId_to_qvector; std::map, float> map_mixed_eventId_to_centrality; + std::map, int> map_mixed_eventId_to_occupancy; std::map, uint64_t> map_mixed_eventId_to_globalBC; std::vector> used_trackIds; @@ -1210,13 +1226,6 @@ struct Dilepton { // run mixed event loop for flow measurement. Don't divide mixed-event categories by event planes, if you do flow measurement. if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kFlowV2) || cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kFlowV3)) { - // if (selected_posTracks_in_this_event.size() + selected_negTracks_in_this_event.size() <= 0) { - // continue; - // } - // fRegistry.fill(HIST("Pair/mix/ev1/hPrf_SP12_CentFT0C"), centrality, RecoDecay::dotProd(qvectors[nmod][cfgQvecEstimator], qvectors[nmod][subdet2])); // current collision - // fRegistry.fill(HIST("Pair/mix/ev1/hPrf_SP13_CentFT0C"), centrality, RecoDecay::dotProd(qvectors[nmod][cfgQvecEstimator], qvectors[nmod][subdet3])); // current collision - // fRegistry.fill(HIST("Pair/mix/ev1/hPrf_SP23_CentFT0C"), centrality, RecoDecay::dotProd(qvectors[nmod][subdet2], qvectors[nmod][subdet3])); // current collision - for (int epbin_tmp = 0; epbin_tmp < static_cast(ep_bin_edges.size()) - 1; epbin_tmp++) { std::tuple key_bin = std::make_tuple(zbin, centbin, epbin_tmp, occbin); auto collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. @@ -1230,6 +1239,7 @@ struct Dilepton { } auto centrality_mix = map_mixed_eventId_to_centrality[mix_dfId_collisionId]; + auto occupancy_mix = map_mixed_eventId_to_occupancy[mix_dfId_collisionId]; auto qvectors_mix = map_mixed_eventId_to_qvector[mix_dfId_collisionId]; auto globalBC_mix = map_mixed_eventId_to_globalBC[mix_dfId_collisionId]; uint64_t diffBC = std::max(collision.globalBC(), globalBC_mix) - std::min(collision.globalBC(), globalBC_mix); @@ -1237,35 +1247,31 @@ struct Dilepton { continue; } - // fRegistry.fill(HIST("Pair/mix/ev2/hPrf_SP12_CentFT0C"), centrality_mix, RecoDecay::dotProd(qvectors_mix[nmod][cfgQvecEstimator], qvectors_mix[nmod][subdet2])); // another collision - // fRegistry.fill(HIST("Pair/mix/ev2/hPrf_SP13_CentFT0C"), centrality_mix, RecoDecay::dotProd(qvectors_mix[nmod][cfgQvecEstimator], qvectors_mix[nmod][subdet3])); // another collision - // fRegistry.fill(HIST("Pair/mix/ev2/hPrf_SP23_CentFT0C"), centrality_mix, RecoDecay::dotProd(qvectors_mix[nmod][subdet2], qvectors_mix[nmod][subdet3])); // another collision - auto posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); auto negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); // LOGF(info, "Do event mixing: current event (%d, %d) | event pool (%d, %d), npos = %d , nneg = %d", ndf, collision.globalIndex(), mix_dfId, mix_collisionId, posTracks_from_event_pool.size(), negTracks_from_event_pool.size()); for (auto& pos : selected_posTracks_in_this_event) { // ULS mix for (auto& neg : negTracks_from_event_pool) { - fillMixedPairInfoForFlow(pos, neg, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix); + fillMixedPairInfoForFlow(pos, neg, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix, collision.trackOccupancyInTimeRange(), occupancy_mix); } } for (auto& neg : selected_negTracks_in_this_event) { // ULS mix for (auto& pos : posTracks_from_event_pool) { - fillMixedPairInfoForFlow(neg, pos, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix); + fillMixedPairInfoForFlow(neg, pos, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix, collision.trackOccupancyInTimeRange(), occupancy_mix); } } for (auto& pos1 : selected_posTracks_in_this_event) { // LS++ mix for (auto& pos2 : posTracks_from_event_pool) { - fillMixedPairInfoForFlow(pos1, pos2, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix); + fillMixedPairInfoForFlow(pos1, pos2, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix, collision.trackOccupancyInTimeRange(), occupancy_mix); } } for (auto& neg1 : selected_negTracks_in_this_event) { // LS-- mix for (auto& neg2 : negTracks_from_event_pool) { - fillMixedPairInfoForFlow(neg1, neg2, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix); + fillMixedPairInfoForFlow(neg1, neg2, cut, qvectors, qvectors_mix, collision.centFT0C(), centrality_mix, collision.trackOccupancyInTimeRange(), occupancy_mix); } } } // end of loop over mixed event pool @@ -1278,6 +1284,7 @@ struct Dilepton { if (nmod > 0) { map_mixed_eventId_to_qvector[key_df_collision] = qvectors; map_mixed_eventId_to_centrality[key_df_collision] = collision.centFT0C(); + map_mixed_eventId_to_occupancy[key_df_collision] = collision.trackOccupancyInTimeRange(); } map_mixed_eventId_to_globalBC[key_df_collision] = collision.globalBC(); emh_pos->AddCollisionIdAtLast(key_bin, key_df_collision); @@ -1290,7 +1297,7 @@ struct Dilepton { } // end of DF template - bool fillMixedPairInfoForFlow(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TQvectors const& qvectors, TMixedQvectors const& qvectors_mix, const float centrality, const float centrality_mix) + bool fillMixedPairInfoForFlow(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TQvectors const& qvectors, TMixedQvectors const& qvectors_mix, const float centrality, const float centrality_mix, const int occupancy, const int occupancy_mix) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto v1ambIds = t1.ambiguousElectronsIds(); @@ -1331,8 +1338,8 @@ struct Dilepton { pair_dca = std::sqrt((dca_t1 * dca_t1 + dca_t2 * dca_t2) / 2.); } - float sp1 = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v1.Phi())), static_cast(std::sin(nmod * v1.Phi()))}, qvectors[nmod][cfgQvecEstimator]) / getSPresolution(centrality); - float sp2 = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v2.Phi())), static_cast(std::sin(nmod * v2.Phi()))}, qvectors_mix[nmod][cfgQvecEstimator]) / getSPresolution(centrality_mix); + float sp1 = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v1.Phi())), static_cast(std::sin(nmod * v1.Phi()))}, qvectors[nmod][cfgQvecEstimator]) / getSPresolution(centrality, occupancy); + float sp2 = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v2.Phi())), static_cast(std::sin(nmod * v2.Phi()))}, qvectors_mix[nmod][cfgQvecEstimator]) / getSPresolution(centrality_mix, occupancy_mix); float cos_dphi1 = std::cos(nmod * (v1.Phi() - v12.Phi())); float cos_dphi2 = std::cos(nmod * (v2.Phi() - v12.Phi())); float cos_dphi12 = std::cos(nmod * (v1.Phi() - v2.Phi())); diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 8367142e9f9..282c01bd363 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -150,8 +150,6 @@ struct DileptonMC { 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_TOFbeta{"cfg_min_TOFbeta", 0.985, "min TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp - Configurable cfg_max_TOFbeta{"cfg_max_TOFbeta", 1.015, "max TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -502,7 +500,6 @@ struct DileptonMC { fDielectronCut.SetMaxDcaZ(dielectroncuts.cfg_max_dcaz); // for eID - fDielectronCut.SetTOFbetaRange(dielectroncuts.cfg_min_TOFbeta, dielectroncuts.cfg_max_TOFbeta); fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); @@ -786,7 +783,7 @@ struct DileptonMC { break; } } // end of primary/secondary selection - } // end of primary selection for same mother + } // end of primary selection for same mother } else if (hfee_type > -1) { if ((t1mc.isPhysicalPrimary() || t1mc.producedByGenerator()) && (t2mc.isPhysicalPrimary() || t2mc.producedByGenerator())) { auto mp1 = mcparticles.iteratorAt(t1mc.mothersIds()[0]); @@ -880,7 +877,7 @@ struct DileptonMC { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi) && ((dielectroncuts.cfg_min_TOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < dielectroncuts.cfg_max_TOFbeta) || o2::aod::pidtofbeta::beta < 0.f); + Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Preslice perCollision_muon = aod::emprimarymuon::emeventId; @@ -916,12 +913,12 @@ struct DileptonMC { // LOGF(info, "centrality = %f , posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", centralities[cfgCentEstimator], posTracks_per_coll.size(), negTracks_per_coll.size()); for (auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - auto mcpos = pos.template emmcparticle_as(); + auto mcpos = mcparticles.iteratorAt(pos.emmcparticleId()); auto mccollision_from_pos = mcpos.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_pos.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - auto mcneg = neg.template emmcparticle_as(); + auto mcneg = mcparticles.iteratorAt(neg.emmcparticleId()); auto mccollision_from_neg = mcneg.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_neg.getSubGeneratorId() != cfgEventGeneratorType) { continue; @@ -931,32 +928,32 @@ struct DileptonMC { } // end of ULS pair loop for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - auto mcpos1 = pos1.template emmcparticle_as(); + auto mcpos1 = mcparticles.iteratorAt(pos1.emmcparticleId()); auto mccollision_from_pos1 = mcpos1.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_pos1.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - auto mcpos2 = pos2.template emmcparticle_as(); + auto mcpos2 = mcparticles.iteratorAt(pos2.emmcparticleId()); auto mccollision_from_pos2 = mcpos2.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_pos2.getSubGeneratorId() != cfgEventGeneratorType) { continue; } fillTruePairInfo(collision, pos1, pos2, cut, mcparticles); - } // end of ULS pair loop + } // end of LS++ pair loop for (auto& [neg1, neg2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - auto mcneg1 = neg1.template emmcparticle_as(); + auto mcneg1 = mcparticles.iteratorAt(neg1.emmcparticleId()); auto mccollision_from_neg1 = mcneg1.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_neg1.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - auto mcneg2 = neg2.template emmcparticle_as(); + auto mcneg2 = mcparticles.iteratorAt(neg2.emmcparticleId()); auto mccollision_from_neg2 = mcneg2.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_neg2.getSubGeneratorId() != cfgEventGeneratorType) { continue; } fillTruePairInfo(collision, neg1, neg2, cut, mcparticles); - } // end of ULS pair loop + } // end of LS-- pair loop } // end of collision loop @@ -1181,7 +1178,7 @@ struct DileptonMC { break; } } // end of HF evaluation - } // end of true ULS pair loop + } // end of true ULS pair loop for (auto& [t1, t2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LOGF(info, "pdg1 = %d, pdg2 = %d", t1.pdgCode(), t2.pdgCode()); @@ -1420,50 +1417,7 @@ struct DileptonMC { } } } // end of true LS++ pair loop - } // end of collision loop - - // for oemga, phi efficiency - for (auto& collision : collisions) { - float centralities[4] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centNTPV()}; - if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { - continue; - } - - if (!fEMEventCut.IsSelected(collision)) { - continue; - } - auto mccollision = collision.template emmcevent_as(); - auto mctracks_per_coll = mcparticles.sliceBy(perMcCollision, mccollision.globalIndex()); - - for (auto& mctrack : mctracks_per_coll) { - - if (!(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { - continue; - } - - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (mctrack.y() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < mctrack.y()) { - continue; - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (mctrack.y() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < mctrack.y()) { - continue; - } - } - - switch (abs(mctrack.pdgCode())) { - case 223: - fRegistry.fill(HIST("Generated/sm/Omega2ll/hPtY"), mctrack.y(), mctrack.pt()); - break; - case 333: - fRegistry.fill(HIST("Generated/sm/Phi2ll/hPtY"), mctrack.y(), mctrack.pt()); - break; - default: - break; - } - - } // end of mctracks per mccollision - } // end of collision loop + } // end of collision loop } template @@ -1499,7 +1453,7 @@ struct DileptonMC { std::map, float> map_weight; // -> float template - void fillPairWeightMap(TCollisions const& collisions, TTracks1 const& posTracks, TTracks2 const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks, TMCCollisions const&, TMCParticles) + void fillPairWeightMap(TCollisions const& collisions, TTracks1 const& posTracks, TTracks2 const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks, TMCCollisions const&, TMCParticles const& mcparticles) { std::vector> passed_pairIds; passed_pairIds.reserve(posTracks.size() * negTracks.size()); @@ -1524,12 +1478,12 @@ struct DileptonMC { auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); for (auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - auto mcpos = pos.template emmcparticle_as(); + auto mcpos = mcparticles.iteratorAt(pos.emmcparticleId()); auto mccollision_from_pos = mcpos.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_pos.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - auto mcneg = neg.template emmcparticle_as(); + auto mcneg = mcparticles.iteratorAt(neg.emmcparticleId()); auto mccollision_from_neg = mcneg.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_neg.getSubGeneratorId() != cfgEventGeneratorType) { continue; @@ -1540,12 +1494,12 @@ struct DileptonMC { } } for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - auto mcpos1 = pos1.template emmcparticle_as(); + auto mcpos1 = mcparticles.iteratorAt(pos1.emmcparticleId()); auto mccollision_from_pos1 = mcpos1.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_pos1.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - auto mcpos2 = pos2.template emmcparticle_as(); + auto mcpos2 = mcparticles.iteratorAt(pos2.emmcparticleId()); auto mccollision_from_pos2 = mcpos2.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_pos2.getSubGeneratorId() != cfgEventGeneratorType) { continue; @@ -1556,12 +1510,12 @@ struct DileptonMC { } } for (auto& [neg1, neg2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - auto mcneg1 = neg1.template emmcparticle_as(); + auto mcneg1 = mcparticles.iteratorAt(neg1.emmcparticleId()); auto mccollision_from_neg1 = mcneg1.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_neg1.getSubGeneratorId() != cfgEventGeneratorType) { continue; } - auto mcneg2 = neg2.template emmcparticle_as(); + auto mcneg2 = mcparticles.iteratorAt(neg2.emmcparticleId()); auto mccollision_from_neg2 = mcneg2.template emmcevent_as(); if (cfgEventGeneratorType >= 0 && mccollision_from_neg2.getSubGeneratorId() != cfgEventGeneratorType) { continue; @@ -1618,8 +1572,8 @@ struct DileptonMC { Partition positive_muonsMC = o2::aod::mcparticle::pdgCode == -13; // mu+ Partition negative_muonsMC = o2::aod::mcparticle::pdgCode == 13; // mu- PresliceUnsorted perMcCollision = aod::emmcparticle::emmceventId; + PresliceUnsorted perMcCollision_vm = aod::emmcgenvectormeson::emmceventId; - // void processAnalysis(FilteredMyCollisions const& collisions, aod::EMMCEvents const& mccollisions, aod::EMMCParticles const& mcparticles, Types const&...) void processAnalysis(FilteredMyCollisions const& collisions, aod::EMMCEvents const& mccollisions, aod::EMMCParticles const& mcparticles, TLeptons const& leptons) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { @@ -1663,6 +1617,56 @@ struct DileptonMC { } PROCESS_SWITCH(DileptonMC, processAnalysis_Smeared, "run dilepton mc analysis with smearing", false); + void processGen_VM(FilteredMyCollisions const& collisions, aod::EMMCEvents const&, aod::EMMCGenVectorMesons const& mcparticles) + { + // for oemga, phi efficiency + for (auto& collision : collisions) { + float centralities[4] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centNTPV()}; + if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + auto mccollision = collision.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + auto mctracks_per_coll = mcparticles.sliceBy(perMcCollision_vm, mccollision.globalIndex()); + + for (auto& mctrack : mctracks_per_coll) { + + if (!(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { + continue; + } + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (mctrack.y() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < mctrack.y()) { + continue; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (mctrack.y() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < mctrack.y()) { + continue; + } + } + + switch (abs(mctrack.pdgCode())) { + case 223: + fRegistry.fill(HIST("Generated/sm/Omega2ll/hPtY"), mctrack.y(), mctrack.pt(), 1.f / mctrack.dsf()); + break; + case 333: + fRegistry.fill(HIST("Generated/sm/Phi2ll/hPtY"), mctrack.y(), mctrack.pt(), 1.f / mctrack.dsf()); + break; + default: + break; + } + + } // end of mctracks per mccollision + } // end of collision loop + } + PROCESS_SWITCH(DileptonMC, processGen_VM, "process generated info for vector mesons", false); + void processDummy(MyCollisions const&) {} PROCESS_SWITCH(DileptonMC, processDummy, "Dummy function", false); }; diff --git a/PWGEM/Dilepton/Core/PhotonHBT.h b/PWGEM/Dilepton/Core/PhotonHBT.h index 2491ba70d96..7d8958d2372 100644 --- a/PWGEM/Dilepton/Core/PhotonHBT.h +++ b/PWGEM/Dilepton/Core/PhotonHBT.h @@ -186,8 +186,6 @@ struct PhotonHBT { 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_TOFbeta{"cfg_min_TOFbeta", 0.985, "min TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp - Configurable cfg_max_TOFbeta{"cfg_max_TOFbeta", 1.015, "max TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp Configurable cfg_min_its_cluster_size{"cfg_min_its_cluster_size", 0.f, "min ITS cluster size"}; Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; Configurable cfg_max_p_its_cluster_size{"cfg_max_p_its_cluster_size", 0.2, "max p to apply ITS cluster size cut"}; @@ -205,6 +203,7 @@ struct PhotonHBT { Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3.0, "max. TPC n sigma for proton exclusion"}; Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3.0, "min. TOF n sigma for electron inclusion"}; Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3.0, "max. TOF n sigma for electron inclusion"}; + Configurable cfg_max_pin_pirejTPC{"cfg_max_pin_pirejTPC", 0.5, "max. pin for pion rejection in TPC"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; // CCDB configuration for PID ML @@ -404,18 +403,18 @@ struct PhotonHBT { const AxisSpec axis_qinv{60, 0.0, +0.3, "q_{inv} (GeV/c)"}; const AxisSpec axis_kstar{60, 0.0, +0.3, "k* (GeV/c)"}; const AxisSpec axis_qabs_lcms{60, 0.0, +0.3, "|#bf{q}|^{LCMS} (GeV/c)"}; - const AxisSpec axis_qout{60, -0.3, +0.3, "q_{out} (GeV/c)"}; // qout does not change between LAB and LCMS frame - const AxisSpec axis_qside{60, -0.3, +0.3, "q_{side} (GeV/c)"}; // qside does not change between LAB and LCMS frame - const AxisSpec axis_qlong{60, -0.3, +0.3, "q_{long} (GeV/c)"}; - - if constexpr (pairtype == ggHBTPairType::kPCMPCM) { // identical particle femtoscopy - fRegistry.add("Pair/same/hs_1d", "diphoton correlation 1D", kTHnSparseD, {axis_qinv, axis_qabs_lcms, axis_kt}, true); - } else { // non-identical particle femtoscopy - fRegistry.add("Pair/same/hs_1d", "diphoton correlation 1D", kTHnSparseD, {axis_kstar, axis_qabs_lcms, axis_kt}, true); - } + const AxisSpec axis_qout{60, 0.0, +0.3, "q_{out} (GeV/c)"}; // qout does not change between LAB and LCMS frame + const AxisSpec axis_qside{60, 0.0, +0.3, "q_{side} (GeV/c)"}; // qside does not change between LAB and LCMS frame + const AxisSpec axis_qlong{60, 0.0, +0.3, "q_{long} (GeV/c)"}; if (cfgDo3D) { fRegistry.add("Pair/same/hs_3d", "diphoton correlation 3D LCMS", kTHnSparseD, {axis_qout, axis_qside, axis_qlong, axis_kt}, true); + } else { + if constexpr (pairtype == ggHBTPairType::kPCMPCM) { // identical particle femtoscopy + fRegistry.add("Pair/same/hs_1d", "diphoton correlation 1D", kTHnSparseD, {axis_qinv, axis_qabs_lcms, axis_kt}, true); + } else { // non-identical particle femtoscopy + fRegistry.add("Pair/same/hs_1d", "diphoton correlation 1D", kTHnSparseD, {axis_kstar, axis_qabs_lcms, axis_kt}, true); + } } if constexpr (pairtype == ggHBTPairType::kPCMPCM) { // dr, dz of conversion points @@ -527,7 +526,6 @@ struct PhotonHBT { fDielectronCut.SetMaxDcaZ(dielectroncuts.cfg_max_dcaz); // for eID - fDielectronCut.SetTOFbetaRange(dielectroncuts.cfg_min_TOFbeta, dielectroncuts.cfg_max_TOFbeta); fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); @@ -535,6 +533,7 @@ struct PhotonHBT { fDielectronCut.SetTPCNsigmaKaRange(dielectroncuts.cfg_min_TPCNsigmaKa, dielectroncuts.cfg_max_TPCNsigmaKa); fDielectronCut.SetTPCNsigmaPrRange(dielectroncuts.cfg_min_TPCNsigmaPr, dielectroncuts.cfg_max_TPCNsigmaPr); fDielectronCut.SetTOFNsigmaElRange(dielectroncuts.cfg_min_TOFNsigmaEl, dielectroncuts.cfg_max_TOFNsigmaEl); + fDielectronCut.SetMaxPinForPionRejectionTPC(dielectroncuts.cfg_max_pin_pirejTPC); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut eid_bdt = new o2::ml::OnnxModel(); @@ -558,19 +557,16 @@ struct PhotonHBT { template void fillPairHistogram(TCollision const&, const ROOT::Math::PtEtaPhiMVector v1, const ROOT::Math::PtEtaPhiMVector v2, const float weight = 1.f) { - // Lab. frame ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); // for identical particles -> qinv = 2 x kstar float kt = k12.Pt(); - // float mt = std::sqrt(std::pow(k12.M(), 2) + std::pow(kt, 2)); // ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - // float qlong_lab = q_3d.Dot(uv_long); ROOT::Math::PxPyPzEVector v1_cartesian(v1); ROOT::Math::PxPyPzEVector v2_cartesian(v2); @@ -589,11 +585,14 @@ struct PhotonHBT { float qlong_lcms = q_3d_lcms.Dot(uv_long); float qabs_lcms = q_3d_lcms.R(); + // float qabs_lcms_tmp = std::sqrt(std::pow(qout_lcms, 2) + std::pow(qside_lcms, 2) + std::pow(qlong_lcms, 2)); + // LOGF(info, "qabs_lcms = %f, qabs_lcms_tmp = %f", qabs_lcms, qabs_lcms_tmp); + // pair rest frame (PRF) ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-beta_x, -beta_y, -beta_z); - ROOT::Math::PxPyPzEVector v1_pfr = boostPRF(v1_cartesian); - ROOT::Math::PxPyPzEVector v2_pfr = boostPRF(v2_cartesian); - ROOT::Math::PxPyPzEVector rel_k = v1_pfr - v2_pfr; + ROOT::Math::PxPyPzEVector v1_prf = boostPRF(v1_cartesian); + ROOT::Math::PxPyPzEVector v2_prf = boostPRF(v2_cartesian); + ROOT::Math::PxPyPzEVector rel_k = v1_prf - v2_prf; float kstar = 0.5 * rel_k.P(); // LOGF(info, "qabs_lcms = %f, qinv = %f, kstar = %f", qabs_lcms, qinv, kstar); @@ -611,13 +610,14 @@ struct PhotonHBT { // float qabs_lcms_tmp = q12_lcms.P(); // LOGF(info, "qabs_lcms = %f, qabs_lcms_tmp = %f", qabs_lcms, qabs_lcms_tmp); - if constexpr (pairtype == ggHBTPairType::kPCMPCM) { // identical particle femtoscopy - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_1d"), qinv, qabs_lcms, kt, weight); - } else { - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_1d"), kstar, qabs_lcms, kt, weight); - } if (cfgDo3D) { - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_3d"), qout_lcms, qside_lcms, qlong_lcms, kt, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_3d"), fabs(qout_lcms), fabs(qside_lcms), fabs(qlong_lcms), kt, weight); // qosl can be [-inf, +inf] and CF is symmetric for pos and neg qosl. To reduce stat. unc. absolute value is taken here. + } else { + if constexpr (pairtype == ggHBTPairType::kPCMPCM) { // identical particle femtoscopy + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_1d"), qinv, qabs_lcms, kt, weight); + } else { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_1d"), kstar, qabs_lcms, kt, weight); + } } } @@ -1189,7 +1189,7 @@ struct PhotonHBT { } Filter trackFilter = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi) && ((dielectroncuts.cfg_min_TOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < dielectroncuts.cfg_max_TOFbeta) || o2::aod::pidtofbeta::beta < 0.f); + Filter pidFilter = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0); diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 85c2212a004..47079887fff 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -115,8 +115,6 @@ struct SingleTrackQC { Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; Configurable cfg_require_itsib_any{"cfg_require_itsib_any", false, "flag to require ITS ib any hits"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", true, "flag to require ITS ib 1st hit"}; - Configurable cfg_min_TOFbeta{"cfg_min_TOFbeta", 0.985, "min TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp - Configurable cfg_max_TOFbeta{"cfg_max_TOFbeta", 1.015, "max TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -319,7 +317,6 @@ struct SingleTrackQC { fDielectronCut.RequireITSib1st(dielectroncuts.cfg_require_itsib_1st); // for eID - fDielectronCut.SetTOFbetaRange(dielectroncuts.cfg_min_TOFbeta, dielectroncuts.cfg_max_TOFbeta); fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); @@ -614,7 +611,7 @@ struct SingleTrackQC { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi) && ((dielectroncuts.cfg_min_TOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < dielectroncuts.cfg_max_TOFbeta) || o2::aod::pidtofbeta::beta < 0.f); + Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Preslice perCollision_muon = aod::emprimarymuon::emeventId; diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index 2e126a80cfa..cd600cf7aed 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -118,8 +118,6 @@ struct SingleTrackQCMC { Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; Configurable cfg_require_itsib_any{"cfg_require_itsib_any", false, "flag to require ITS ib any hits"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", true, "flag to require ITS ib 1st hit"}; - Configurable cfg_min_TOFbeta{"cfg_min_TOFbeta", 0.985, "min TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp - Configurable cfg_max_TOFbeta{"cfg_max_TOFbeta", 1.015, "max TOF beta for single track"}; //|beta - 1| < 0.015 corresponds to 3 sigma in pp Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -365,7 +363,6 @@ struct SingleTrackQCMC { fDielectronCut.RequireITSib1st(dielectroncuts.cfg_require_itsib_1st); // for eID - fDielectronCut.SetTOFbetaRange(dielectroncuts.cfg_min_TOFbeta, dielectroncuts.cfg_max_TOFbeta); fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); @@ -873,7 +870,7 @@ struct SingleTrackQCMC { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi) && ((dielectroncuts.cfg_min_TOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < dielectroncuts.cfg_max_TOFbeta) || o2::aod::pidtofbeta::beta < 0.f); + Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Preslice perCollision_muon = aod::emprimarymuon::emeventId; diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index bf585c56c43..27b99a6e9b3 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -244,7 +244,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! Particle rapidity }); } // namespace emmcparticle -// This table contains all MC truth tracks (both v0 and calos) +// This table contains all MC truth tracks DECLARE_SOA_TABLE_FULL(EMMCParticles, "EMMCParticles", "AOD", "EMMCPARTICLE", //! MC track information (on disk) o2::soa::Index<>, emmcparticle::EMMCEventId, mcparticle::PdgCode, mcparticle::Flags, @@ -265,6 +265,31 @@ DECLARE_SOA_TABLE_FULL(EMMCParticles, "EMMCParticles", "AOD", "EMMCPARTICLE", // using EMMCParticle = EMMCParticles::iterator; +namespace emmcgenvectormeson +{ +DECLARE_SOA_INDEX_COLUMN(EMMCEvent, emmcevent); +DECLARE_SOA_COLUMN(DownScalingFactor, dsf, float); //! down scaling factor to store this mc particle in reduced AO2D.root +} // namespace emmcgenvectormeson + +DECLARE_SOA_TABLE_FULL(EMMCGenVectorMesons, "EMMCGenVectorMesons", "AOD", "EMMCGENVM", //! generated omega, phi information + o2::soa::Index<>, emmcgenvectormeson::EMMCEventId, + mcparticle::PdgCode, mcparticle::Flags, + mcparticle::Px, mcparticle::Py, mcparticle::Pz, mcparticle::E, + emmcgenvectormeson::DownScalingFactor, + + // dynamic column + emmcparticle::Pt, + emmcparticle::Eta, + emmcparticle::Phi, + + emmcparticle::P, + emmcparticle::Y, + mcparticle::ProducedByGenerator, + mcparticle::FromBackgroundEvent, + mcparticle::IsPhysicalPrimary); + +using EMMCGenVectorMeson = EMMCGenVectorMesons::iterator; + namespace smearedtrack { DECLARE_SOA_COLUMN(PtSmeared, ptSmeared, float); @@ -330,6 +355,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float pt, float eta) -> float { return pt * 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); }); DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, [](float pt, float eta) -> float { return pt * std::sinh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, [](float tgl) -> float { return M_PI_2 - std::atan(tgl); }); DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITS, meanClusterSizeITS, [](uint32_t itsClusterSizes) -> float { int total_cluster_size = 0, nl = 0; for (unsigned int layer = 0; layer < 7; layer++) { @@ -399,6 +425,7 @@ DECLARE_SOA_TABLE(EMPrimaryElectrons, "AOD", "EMPRIMARYEL", //! emprimaryelectron::Px, emprimaryelectron::Py, emprimaryelectron::Pz, + emprimaryelectron::Theta, emprimaryelectron::MeanClusterSizeITS, emprimaryelectron::MeanClusterSizeITSib, emprimaryelectron::MeanClusterSizeITSob); @@ -451,6 +478,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float pt, float eta) -> float { return pt * 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); }); DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, [](float pt, float eta) -> float { return pt * std::sinh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, [](float tgl) -> float { return M_PI_2 - std::atan(tgl); }); DECLARE_SOA_DYNAMIC_COLUMN(DcaXY, dcaXY, [](float dcaX, float dcaY) -> float { return std::sqrt(dcaX * dcaX + dcaY * dcaY); }); DECLARE_SOA_DYNAMIC_COLUMN(NClustersMFT, nClustersMFT, //! Number of MFT clusters [](uint64_t mftClusterSizesAndTrackFlags) -> uint8_t { @@ -495,6 +523,7 @@ DECLARE_SOA_TABLE(EMPrimaryMuons, "AOD", "EMPRIMARYMU", //! emprimarymuon::Px, emprimarymuon::Py, emprimarymuon::Pz, + emprimarymuon::Theta, emprimarymuon::DcaXY); // iterators using EMPrimaryMuon = EMPrimaryMuons::iterator; diff --git a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx index 88a6a1352fd..6cf6b0865d0 100644 --- a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx @@ -14,6 +14,7 @@ // This code produces reduced events for photon analyses. // Please write to: daiki.sekihata@cern.ch +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" @@ -42,22 +43,31 @@ struct AssociateMCInfoDilepton { Produces mcevents; Produces mceventlabels; Produces emmcparticles; + Produces emmcgenvms; Produces v0legmclabels; Produces emprimaryelectronmclabels; Produces emprimarymuonmclabels; + Configurable down_scaling_omega{"down_scaling_omega", 1.0, "down scaling factor to store omega"}; + Configurable down_scaling_phi{"down_scaling_phi", 1.0, "down scaling factor to store phi"}; Configurable min_eta_gen_primary{"min_eta_gen_primary", -1.2, "min rapidity Y to store generated information"}; // smearing might be applied at analysis stage. set wider value. Configurable max_eta_gen_primary{"max_eta_gen_primary", +1.2, "max rapidity Y to store generated information"}; // smearing might be applied at analysis stage. set wider value. Configurable min_eta_gen_primary_fwd{"min_eta_gen_primary_fwd", -4.5, "min eta to store generated information"}; // smearing might be applied at analysis stage. set wider value. Configurable max_eta_gen_primary_fwd{"max_eta_gen_primary_fwd", -2.0, "max eta to store generated information"}; // smearing might be applied at analysis stage. set wider value. HistogramRegistry registry{"EMMCEvent"}; + std::mt19937 engine; + std::uniform_real_distribution dist01; void init(o2::framework::InitContext&) { auto hEventCounter = registry.add("hEventCounter", "hEventCounter", kTH1I, {{6, 0.5f, 6.5f}}); hEventCounter->GetXaxis()->SetBinLabel(1, "all"); hEventCounter->GetXaxis()->SetBinLabel(2, "has mc collision"); + + std::random_device seed_gen; + engine = std::mt19937(seed_gen()); + dist01 = std::uniform_real_distribution(0.0f, 1.0f); } template @@ -156,12 +166,15 @@ struct AssociateMCInfoDilepton { auto mcCollision = collision.mcCollision(); mceventlabels(fEventLabels.find(mcCollision.globalIndex())->second, collision.mcMask()); + } // end of reconstructed collision loop + + for (auto& mcCollision : mcCollisions) { // store MC true information - auto mcelectrons_per_collision = mcelectrons.sliceBy(perMcCollision, mcCollision.globalIndex()); - auto mcmuons_per_collision = mcmuons.sliceBy(perMcCollision, mcCollision.globalIndex()); - auto mcvectormesons_per_collision = mcvectormesons.sliceBy(perMcCollision, mcCollision.globalIndex()); + auto mcelectrons_per_mccollision = mcelectrons.sliceBy(perMcCollision, mcCollision.globalIndex()); + auto mcmuons_per_mccollision = mcmuons.sliceBy(perMcCollision, mcCollision.globalIndex()); + auto mcvectormesons_per_mccollision = mcvectormesons.sliceBy(perMcCollision, mcCollision.globalIndex()); - for (auto& mctrack : mcelectrons_per_collision) { // store necessary information for denominator of efficiency + for (auto& mctrack : mcelectrons_per_mccollision) { // store necessary information for denominator of efficiency if (!mctrack.isPhysicalPrimary() && !mctrack.producedByGenerator()) { continue; } @@ -213,7 +226,7 @@ struct AssociateMCInfoDilepton { } // end of ndau protection } // end of mc electron loop - for (auto& mctrack : mcmuons_per_collision) { // store necessary information for denominator of efficiency + for (auto& mctrack : mcmuons_per_mccollision) { // store necessary information for denominator of efficiency if (!mctrack.isPhysicalPrimary() && !mctrack.producedByGenerator()) { continue; } @@ -265,7 +278,7 @@ struct AssociateMCInfoDilepton { } // end of ndau protection } // end of mc muon loop - for (auto& mctrack : mcvectormesons_per_collision) { // store necessary information for denominator of efficiency + for (auto& mctrack : mcvectormesons_per_mccollision) { // store necessary information for denominator of efficiency // Be careful!! dilepton rapidity is different from meson rapidity! No acceptance cut here. if (!mctrack.isPhysicalPrimary() && !mctrack.producedByGenerator()) { @@ -291,22 +304,21 @@ struct AssociateMCInfoDilepton { // store daughter of vector mesons if (mctrack.has_daughters()) { - // bool is_lepton_involved = false; - // for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { - // // TODO: remove this check as soon as issues with MC production are fixed - // if (d < mcTracks.size()) { // protect against bad daughter indices - // auto daughter = mcTracks.iteratorAt(d); - // if (abs(daughter.pdgCode()) == 11 || abs(daughter.pdgCode()) == 13) { - // is_lepton_involved = true; - // break; - // } - // } else { - // std::cout << "Daughter label (" << d << ") exceeds the McParticles size (" << mcTracks.size() << ")" << std::endl; - // std::cout << " Check the MC generator" << std::endl; - // } - // } + bool is_lepton_involved = false; + for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { + // TODO: remove this check as soon as issues with MC production are fixed + if (d < mcTracks.size()) { // protect against bad daughter indices + auto daughter = mcTracks.iteratorAt(d); + if (abs(daughter.pdgCode()) == 11 || abs(daughter.pdgCode()) == 13) { + is_lepton_involved = true; + break; + } + } else { + std::cout << "Daughter label (" << d << ") exceeds the McParticles size (" << mcTracks.size() << ")" << std::endl; + std::cout << " Check the MC generator" << std::endl; + } + } - bool is_lepton_involved = true; if (is_lepton_involved) { // LOGF(info, "daughter range in original MC stack pdg = %d | %d - %d , n dau = %d", mctrack.pdgCode(), mctrack.daughtersIds()[0], mctrack.daughtersIds()[1], mctrack.daughtersIds()[1] -mctrack.daughtersIds()[0] +1); for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { @@ -331,32 +343,7 @@ struct AssociateMCInfoDilepton { } // end of ndau protection } // end of generated vector mesons loop - for (auto& mctrack : mcvectormesons_per_collision) { // store necessary information for denominator of efficiency - // Be careful!! dilepton rapidity is different from meson rapidity! No acceptance cut here. - - if (!mctrack.isPhysicalPrimary() && !mctrack.producedByGenerator()) { - continue; - } - - if ((mctrack.y() < min_eta_gen_primary || max_eta_gen_primary < mctrack.y()) && (mctrack.y() < min_eta_gen_primary_fwd || max_eta_gen_primary_fwd < mctrack.y())) { // acceptance cut to mesons - continue; - } - - auto mcCollision = mcCollisions.iteratorAt(mctrack.mcCollisionId()); - - int ndau = mctrack.daughtersIds()[1] - mctrack.daughtersIds()[0] + 1; - if (ndau < 10) { - if (!(fNewLabels.find(mctrack.globalIndex()) != fNewLabels.end())) { - fNewLabels[mctrack.globalIndex()] = fCounters[0]; - fNewLabelsReversed[fCounters[0]] = mctrack.globalIndex(); - // fMCFlags[mctrack.globalIndex()] = mcflags; - fEventIdx[mctrack.globalIndex()] = fEventLabels.find(mcCollision.globalIndex())->second; - fCounters[0]++; - } - } // end of ndau protection - } // end of generated vector mesons loop for efficiency of omega, phi pT spectra - - } // end of reconstructed collision loop + } // end of mc collision loop if constexpr (static_cast(system & kPCM)) { for (auto& v0 : v0photons) { @@ -587,6 +574,26 @@ struct AssociateMCInfoDilepton { daughters.shrink_to_fit(); } // end loop over labels + // only for omega, phi mesons + for (auto& mcCollision : mcCollisions) { + auto mcvectormesons_per_mccollision = mcvectormesons.sliceBy(perMcCollision, mcCollision.globalIndex()); + for (auto& mctrack : mcvectormesons_per_mccollision) { // store necessary information for denominator of efficiency + if (!mctrack.isPhysicalPrimary() && !mctrack.producedByGenerator()) { + continue; + } + + if (mctrack.pdgCode() == 223) { + if (dist01(engine) < down_scaling_omega) { + emmcgenvms(fEventLabels[mcCollision.globalIndex()], mctrack.pdgCode(), mctrack.flags(), mctrack.px(), mctrack.py(), mctrack.pz(), mctrack.e(), down_scaling_omega.value); + } + } else if (mctrack.pdgCode() == 333) { + if (dist01(engine) < down_scaling_phi) { + emmcgenvms(fEventLabels[mcCollision.globalIndex()], mctrack.pdgCode(), mctrack.flags(), mctrack.px(), mctrack.py(), mctrack.pz(), mctrack.e(), down_scaling_phi.value); + } + } + } // end of generated vector meson loop + } // end of reconstructed collision loop + fNewLabels.clear(); fNewLabelsReversed.clear(); // fMCFlags.clear(); diff --git a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx index fb727ffd41d..603c97138ff 100644 --- a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx @@ -341,7 +341,7 @@ struct EMEventPropertyTask { } spherocity_cuts; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - void init(InitContext& initContext) + void init(InitContext&) { if (fillQAHistogram) { fRegistry.add("Spherocity/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{200, 0.0f, 10}}, false); diff --git a/PWGEM/Dilepton/TableProducer/eventSelection.cxx b/PWGEM/Dilepton/TableProducer/eventSelection.cxx index f7bcfc4803a..2c804ddf2d4 100644 --- a/PWGEM/Dilepton/TableProducer/eventSelection.cxx +++ b/PWGEM/Dilepton/TableProducer/eventSelection.cxx @@ -118,5 +118,5 @@ struct EMEventSelection { }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"event-selection"})}; + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"em-event-selection"})}; } diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx index bbeed367428..4c3d50f2356 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx @@ -83,8 +83,6 @@ struct skimmerPrimaryElectron { Configurable maxTPCNsigmaPr{"maxTPCNsigmaPr", 2.5, "max. TPC n sigma for proton exclusion"}; Configurable minTPCNsigmaPr{"minTPCNsigmaPr", -2.5, "min. TPC n sigma for proton exclusion"}; Configurable requireTOF{"requireTOF", false, "require TOF hit"}; - Configurable minTOFbeta{"minTOFbeta", 0.97, "min TOF beta for single track"}; // |beta - 1| < 0.015 corresponds to 3 sigma in pp - Configurable maxTOFbeta{"maxTOFbeta", 1.03, "max TOF beta for single track"}; // |beta - 1| < 0.015 corresponds to 3 sigma in pp HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; @@ -236,7 +234,7 @@ struct skimmerPrimaryElectron { return false; } - if ((0.0 < track.beta() && track.beta() < minTOFbeta) || maxTOFbeta < track.beta()) { + if (track.hasTOF() && (maxTOFNsigmaEl < fabs(track.tofNSigmaEl()))) { return false; } @@ -249,11 +247,11 @@ struct skimmerPrimaryElectron { float dcaXY = dcaInfo[0]; float dcaZ = dcaInfo[1]; - if (abs(dcaXY) > dca_xy_max || abs(dcaZ) > dca_z_max) { + if (fabs(dcaXY) > dca_xy_max || fabs(dcaZ) > dca_z_max) { return false; } - if (track_par_cov_recalc.getPt() < minpt || abs(track_par_cov_recalc.getEta()) > maxeta) { + if (track_par_cov_recalc.getPt() < minpt || fabs(track_par_cov_recalc.getEta()) > maxeta) { return false; } @@ -263,7 +261,7 @@ struct skimmerPrimaryElectron { dca_3d = 999.f; } else { float chi2 = (dcaXY * dcaXY * track_par_cov_recalc.getSigmaZ2() + dcaZ * dcaZ * track_par_cov_recalc.getSigmaY2() - 2. * dcaXY * dcaZ * track_par_cov_recalc.getSigmaZY()) / det; - dca_3d = std::sqrt(std::abs(chi2) / 2.); + dca_3d = std::sqrt(std::fabs(chi2) / 2.); } if (dca_3d > dca_3d_sigma_max) { return false; @@ -293,7 +291,7 @@ struct skimmerPrimaryElectron { if (minTPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < maxTPCNsigmaPr) { return false; } - if (!(track.beta() < 0.f || (minTOFbeta < track.beta() && track.beta() < maxTOFbeta))) { + if (track.hasTOF() && (maxTOFNsigmaEl < fabs(track.tofNSigmaEl()))) { return false; } return true; @@ -305,10 +303,7 @@ struct skimmerPrimaryElectron { if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi) { return false; } - if (!(track.beta() < 0.f || (minTOFbeta < track.beta() && track.beta() < maxTOFbeta))) { - return false; - } - return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && abs(track.tofNSigmaEl()) < maxTOFNsigmaEl; + return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && fabs(track.tofNSigmaEl()) < maxTOFNsigmaEl; } template @@ -404,7 +399,7 @@ struct skimmerPrimaryElectron { 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::tpcChi2NCl < maxchi2tpc&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; - Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl && ((minTOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < maxTOFbeta) || o2::aod::pidtofbeta::beta < 0.f) && (o2::aod::pidtpc::tpcNSigmaPi < minTPCNsigmaPi || maxTPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); + Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl && (o2::aod::pidtpc::tpcNSigmaPi < minTPCNsigmaPi || maxTPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; @@ -728,14 +723,14 @@ struct prefilterPrimaryElectron { o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo); getPxPyPz(track_par_cov_recalc, pVec_recalc); - if (abs(dcaInfo[0]) < min_dcatopv) { + if (fabs(dcaInfo[0]) < min_dcatopv) { return false; } if (isITSonlyTrack(track) && track_par_cov_recalc.getPt() > max_pt_itsonly) { return false; } - if (abs(track_par_cov_recalc.getEta()) > maxeta) { + if (fabs(track_par_cov_recalc.getEta()) > maxeta) { return false; } @@ -786,7 +781,6 @@ struct prefilterPrimaryElectron { Preslice trackIndicesPerCollision = aod::track_association::collisionId; - // Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& min_dcatopv < nabs(o2::aod::track::dcaXY) && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; diff --git a/PWGEM/Dilepton/Tasks/eventQC.cxx b/PWGEM/Dilepton/Tasks/eventQC.cxx index 719fcc8df5c..c7570928c6e 100644 --- a/PWGEM/Dilepton/Tasks/eventQC.cxx +++ b/PWGEM/Dilepton/Tasks/eventQC.cxx @@ -55,11 +55,13 @@ struct eventQC { Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable cfgFillPID{"cfgFillPID", false, "fill PID histograms"}; - Configurable> cfgnMods{"cfgnMods", {2, 3, 4}, "Modulation of interest. Please keep increasing order"}; + Configurable> cfgnMods{"cfgnMods", {2, 3}, "Modulation of interest. Please keep increasing order"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; - ConfigurableAxis ConfPtBins{"ConfPtBins", {VARIABLE_WIDTH, 0.00, 0.05, 0.10, 0.15, 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}, "pT bins for output histograms"}; + ConfigurableAxis ConfPtBins{"ConfPtBins", {VARIABLE_WIDTH, 0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 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}, "pT bins for output histograms"}; + Configurable cfgNbinsEta{"cfgNbinsEta", 40, "number of eta bins for output histograms"}; + Configurable cfgNbinsPhi{"cfgNbinsPhi", 360, "number of phi bins for output histograms"}; struct : ConfigurableGroup { std::string prefix = "eventcut_group"; @@ -135,7 +137,7 @@ struct eventQC { fRegistry.add("Event/before/hCentFT0A", "hCentFT0A;centrality FT0A (%)", kTH1F, {{110, 0, 110}}, false); fRegistry.add("Event/before/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1F, {{110, 0, 110}}, false); fRegistry.add("Event/before/hCentFT0M", "hCentFT0M;centrality FT0M (%)", kTH1F, {{110, 0, 110}}, false); - fRegistry.add("Event/before/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); + fRegistry.add("Event/before/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{100, 0, 100}, {600, 0, 6000}}, false); fRegistry.add("Event/before/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); fRegistry.add("Event/before/hMultFT0CvsOccupancy", "hMultFT0CvsOccupancy;mult. FT0C;N_{track} in time range", kTH2F, {{60, 0, 60000}, {200, 0, 20000}}, false); fRegistry.add("Event/before/hNTracksPVvsOccupancy", "hNTracksPVvsOccupancy;N_{track} to PV;N_{track} in time range", kTH2F, {{600, 0, 6000}, {200, 0, 20000}}, false); @@ -144,10 +146,10 @@ struct eventQC { fRegistry.addClone("Event/before/", "Event/after/"); fRegistry.add("Event/after/hMultNGlobalTracks", "hMultNGlobalTracks; N_{track}^{global}", kTH1F, {{6001, -0.5, 6000.5}}, false); - fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracks", "hCentFT0CvsMultNGlobalTracks;centrality FT0C (%);N_{track}^{global}", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); + fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracks", "hCentFT0CvsMultNGlobalTracks;centrality FT0C (%);N_{track}^{global}", kTH2F, {{100, 0, 100}, {600, 0, 6000}}, false); fRegistry.add("Event/after/hMultFT0CvsMultNGlobalTracks", "hMultFT0CvsMultNGlobalTracks;mult. FT0C;N_{track}^{global}", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); fRegistry.add("Event/after/hMultNGlobalTracksPV", "hMultNGlobalTracksPV; N_{track}^{global} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); - fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracksPV", "hCentFT0CvsMultNGlobalTracksPV;centrality FT0C (%);N_{track}^{global} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); + fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracksPV", "hCentFT0CvsMultNGlobalTracksPV;centrality FT0C (%);N_{track}^{global} to PV", kTH2F, {{100, 0, 100}, {600, 0, 6000}}, false); fRegistry.add("Event/after/hMultFT0CvsMultNGlobalTracksPV", "hMultFT0CvsMultNGlobalTracksPV;mult. FT0C;N_{track}^{global} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); for (int i = 0; i < static_cast(cfgnMods->size()); i++) { @@ -184,18 +186,27 @@ struct eventQC { fRegistry.add(Form("Event/after/Qvector/hPrfQ%dFT0AQ%dFT0C_CentFT0C", nmod, nmod), Form("Q_{%d}^{FT0A} #upoint Q_{%d}^{FT0C};centrality FT0C (%%);Q_{%d}^{FT0A} #upoint Q_{%d}^{FT0C}", nmod, nmod, nmod, nmod), kTProfile, {{100, 0, 100}}, false); } + std::vector tmp_ptbins; + for (int i = 0; i < 100; i++) { + tmp_ptbins.emplace_back(0.01 * i); // every 0.01 GeV/c from 0 to 1 GeV/c + } + for (int i = 0; i < 91; i++) { + tmp_ptbins.emplace_back(0.1 * i + 1.f); // every 0.1 GeV/c from 1 to 10 GeV/c + } + const AxisSpec axis_pt_tmp{tmp_ptbins, "p_{T} (GeV/c)"}; + const AxisSpec axis_pt{ConfPtBins, "p_{T} (GeV/c)"}; - const AxisSpec axis_eta{20, -1.0, +1.0, "#eta"}; - const AxisSpec axis_phi{72, 0.0, 2 * M_PI, "#varphi (rad.)"}; + const AxisSpec axis_eta{cfgNbinsEta, -1.0, +1.0, "#eta"}; + const AxisSpec axis_phi{cfgNbinsPhi, 0.0, 2 * M_PI, "#varphi (rad.)"}; const AxisSpec axis_sign{3, -1.5, +1.5, "sign"}; - fRegistry.add("Track/hs", "rec. single electron", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_sign}, true); + fRegistry.add("Track/hs", "rec. single electron", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_sign}, false); fRegistry.add("Track/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); fRegistry.add("Track/hSigma1Pt", "#sigma_{1/p_{T}} vs. q/p_{T};q/p_{T} (GeV/c)^{-1};#sigma_{1/p_{T}} (GeV/c)^{-1}", kTH2F, {{400, -20, 20}, {200, 0, 0.2}}, false); - fRegistry.add("Track/hRelSigma1Pt", "relative p_{T} resolution;p_{T} (GeV/c);#sigma_{1/p_{T}} #times p_{T}", kTH2F, {{1000, 0, 10}, {100, 0, 0.1}}, false); + fRegistry.add("Track/hRelSigma1Pt", "relative p_{T} resolution;p_{T} (GeV/c);#sigma_{1/p_{T}} #times p_{T}", kTH2F, {axis_pt_tmp, {100, 0, 0.1}}, false); fRegistry.add("Track/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); fRegistry.add("Track/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", kTH2F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}}, false); - fRegistry.add("Track/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{200, 0, 10}, {200, 0., 400}}, false); - fRegistry.add("Track/hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", kTH2F, {{200, 0, 10}, {200, 0., 400}}, false); + fRegistry.add("Track/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {axis_pt_tmp, {500, 0., 500}}, false); + fRegistry.add("Track/hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", kTH2F, {axis_pt_tmp, {500, 0., 500}}, false); fRegistry.add("Track/hNclsTPC", "number of TPC clusters", kTH1F, {{161, -0.5, 160.5}}, false); fRegistry.add("Track/hNcrTPC", "number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, false); fRegistry.add("Track/hChi2TPC", "chi2/number of TPC clusters", kTH1F, {{100, 0, 10}}, false); @@ -294,7 +305,7 @@ struct eventQC { if (collision.sel8()) { fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hCollisionCounter"), 10.0); } - if (abs(collision.posZ()) < 10.0) { + if (fabs(collision.posZ()) < 10.0) { fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hCollisionCounter"), 11.0); } if (collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { @@ -453,7 +464,7 @@ struct eventQC { { bool is_good = true; for (auto& qvec : qvectors) { - if (abs(qvec[0]) > 10.f || abs(qvec[1]) > 10.f) { + if (fabs(qvec[0]) > 20.f || fabs(qvec[1]) > 20.f) { is_good = false; break; } @@ -494,7 +505,7 @@ struct eventQC { return false; } - if (abs(collision.posZ()) > eventcuts.cfgZvtxMax) { + if (fabs(collision.posZ()) > eventcuts.cfgZvtxMax) { return false; } @@ -572,7 +583,7 @@ struct eventQC { } fillTrackInfo(track); - if (abs(track.eta()) < 0.8) { + if (fabs(track.eta()) < 0.8) { nGlobalTracks++; if (track.isPVContributor()) { nGlobalTracksPV++; diff --git a/PWGEM/Dilepton/Tasks/vpPairQC.cxx b/PWGEM/Dilepton/Tasks/vpPairQC.cxx index 9d3eb1cb34e..6f6f23bb45b 100644 --- a/PWGEM/Dilepton/Tasks/vpPairQC.cxx +++ b/PWGEM/Dilepton/Tasks/vpPairQC.cxx @@ -11,7 +11,7 @@ // // ======================== // -// This code runs loop over dalitz ee table for dalitz QC. +// This code runs loop over ULS ee pars for virtual photon QC. // Please write to: daiki.sekihata@cern.ch #include "TString.h" @@ -30,6 +30,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" #include "PWGEM/Dilepton/Utils/EMTrack.h" +#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/Dilepton/Utils/EventHistograms.h" #include "PWGEM/Dilepton/Utils/PairUtilities.h" @@ -121,6 +122,7 @@ struct vpPairQC { Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +0.0, "max. TPC n sigma for proton exclusion"}; Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3.0, "min. TOF n sigma for electron inclusion"}; Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3.0, "max. TOF n sigma for electron inclusion"}; + Configurable cfg_max_pin_pirejTPC{"cfg_max_pin_pirejTPC", 0.5, "max. pin for pion rejection in TPC"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; // CCDB configuration for PID ML @@ -211,6 +213,10 @@ struct vpPairQC { const AxisSpec axis_dca{{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}, "DCA_{e}^{3D} (#sigma)"}; fRegistry.add("Track/positive/hs", "rec. single electron", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca}, true); fRegistry.add("Track/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); + fRegistry.add("Track/positive/hPResolution", "p resolution;p (GeV/c);#Deltap/p", kTH2F, {{1000, 0.0f, 10.0f}, {100, 0.0f, 0.1f}}, false); + fRegistry.add("Track/positive/hPtResolution", "p_{T} resolution;p (GeV/c);#Deltap_{T}/p_{T}", kTH2F, {{1000, 0.0f, 10.0f}, {100, 0.0f, 0.1f}}, false); + fRegistry.add("Track/positive/hThetaResolution", "#theta resolution;p (GeV/c);#Delta#theta (rad.)", kTH2F, {{1000, 0.0f, 10.0f}, {200, 0.0f, 0.02f}}, false); + fRegistry.add("Track/positive/hPhiResolution", "#varphi resolution;p (GeV/c);#Delta#varphi (rad.)", kTH2F, {{1000, 0.0f, 10.0f}, {200, 0.0f, 0.02f}}, false); fRegistry.add("Track/positive/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); fRegistry.add("Track/positive/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", kTH2F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}}, false); fRegistry.add("Track/positive/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{200, 0, 10}, {200, 0., 400}}, false); @@ -238,8 +244,8 @@ struct vpPairQC { 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.addClone("Track/positive/", "Track/negative/"); - const AxisSpec axis_mass{100, 0, 0.1, "m_{ee} (GeV/c^{2})"}; - const AxisSpec axis_pair_pt{100, 0, 1, "p_{T,ee} (GeV/c)"}; + const AxisSpec axis_mass{50, 0, 0.05, "m_{ee} (GeV/c^{2})"}; + const AxisSpec axis_pair_pt{500, 0, 5, "p_{T,ee} (GeV/c)"}; const AxisSpec axis_pair_dca_3d{100, 0, 10, "DCA_{ee}^{3D} (#sigma)"}; const AxisSpec axis_pair_dca_xy{100, 0, 10, "DCA_{ee}^{XY} (#sigma)"}; const AxisSpec axis_phiv{90, 0, M_PI, "#varphi_{V} (rad.)"}; @@ -302,6 +308,7 @@ struct vpPairQC { fDielectronCut.SetTPCNsigmaKaRange(dielectroncuts.cfg_min_TPCNsigmaKa, dielectroncuts.cfg_max_TPCNsigmaKa); fDielectronCut.SetTPCNsigmaPrRange(dielectroncuts.cfg_min_TPCNsigmaPr, dielectroncuts.cfg_max_TPCNsigmaPr); fDielectronCut.SetTOFNsigmaElRange(dielectroncuts.cfg_min_TOFNsigmaEl, dielectroncuts.cfg_max_TOFNsigmaEl); + fDielectronCut.SetMaxPinForPionRejectionTPC(dielectroncuts.cfg_max_pin_pirejTPC); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut eid_bdt = new o2::ml::OnnxModel(); @@ -375,6 +382,10 @@ struct vpPairQC { if (track.sign() > 0) { fRegistry.fill(HIST("Track/positive/hs"), track.pt(), track.eta(), track.phi(), dca_3d, weight); fRegistry.fill(HIST("Track/positive/hQoverPt"), track.sign() / track.pt()); + fRegistry.fill(HIST("Track/positive/hPResolution"), track.p(), sigmaP(track) / track.p()); + fRegistry.fill(HIST("Track/positive/hPtResolution"), track.p(), sigmaPt(track) / track.pt()); + fRegistry.fill(HIST("Track/positive/hThetaResolution"), track.p(), sigmaLambda(track)); + fRegistry.fill(HIST("Track/positive/hPhiResolution"), track.p(), sigmaPhi(track)); fRegistry.fill(HIST("Track/positive/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/positive/hDCAxyzSigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); fRegistry.fill(HIST("Track/positive/hDCAxyRes_Pt"), track.pt(), sqrt(track.cYY()) * 1e+4); // convert cm to um @@ -404,6 +415,10 @@ struct vpPairQC { } else { fRegistry.fill(HIST("Track/negative/hs"), track.pt(), track.eta(), track.phi(), dca_3d, weight); fRegistry.fill(HIST("Track/negative/hQoverPt"), track.sign() / track.pt()); + fRegistry.fill(HIST("Track/negative/hPResolution"), track.p(), sigmaP(track) / track.p()); + fRegistry.fill(HIST("Track/negative/hPtResolution"), track.p(), sigmaPt(track) / track.pt()); + fRegistry.fill(HIST("Track/negative/hThetaResolution"), track.p(), sigmaLambda(track)); + fRegistry.fill(HIST("Track/negative/hPhiResolution"), track.p(), sigmaPhi(track)); fRegistry.fill(HIST("Track/negative/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/negative/hDCAxyzSigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); fRegistry.fill(HIST("Track/negative/hDCAxyRes_Pt"), track.pt(), sqrt(track.cYY()) * 1e+4); // convert cm to um diff --git a/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx b/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx index 07c0cabd5d4..add2cb33b2b 100644 --- a/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx +++ b/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx @@ -11,7 +11,7 @@ // // ======================== // -// This code runs loop over dalitz ee table for dalitz QC. +// This code runs loop over ULS ee pars for virtual photon QC. // Please write to: daiki.sekihata@cern.ch #include "TString.h" @@ -119,6 +119,7 @@ struct vpPairQCMC { Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +0.0, "max. TPC n sigma for proton exclusion"}; Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -0.0, "min. TOF n sigma for electron inclusion"}; Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +0.0, "max. TOF n sigma for electron inclusion"}; + Configurable cfg_max_pin_pirejTPC{"cfg_max_pin_pirejTPC", 0.5, "max. pin for pion rejection in TPC"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; // CCDB configuration for PID ML @@ -310,6 +311,7 @@ struct vpPairQCMC { fDielectronCut.SetTPCNsigmaKaRange(dielectroncuts.cfg_min_TPCNsigmaKa, dielectroncuts.cfg_max_TPCNsigmaKa); fDielectronCut.SetTPCNsigmaPrRange(dielectroncuts.cfg_min_TPCNsigmaPr, dielectroncuts.cfg_max_TPCNsigmaPr); fDielectronCut.SetTOFNsigmaElRange(dielectroncuts.cfg_min_TOFNsigmaEl, dielectroncuts.cfg_max_TOFNsigmaEl); + fDielectronCut.SetMaxPinForPionRejectionTPC(dielectroncuts.cfg_max_pin_pirejTPC); if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDielectronCut // o2::ml::OnnxModel* eid_bdt = new o2::ml::OnnxModel(); @@ -428,7 +430,7 @@ struct vpPairQCMC { break; } } // end of primary/secondary selection - } // end of primary selection for same mother + } // end of primary selection for same mother } // fill track info that belong to true pairs. @@ -606,7 +608,7 @@ struct vpPairQCMC { } } } // end of true ULS pair loop - } // end of collision loop + } // end of collision loop } PROCESS_SWITCH(vpPairQCMC, processGen, "run genrated info", true); diff --git a/PWGEM/Dilepton/Utils/EMTrackUtilities.h b/PWGEM/Dilepton/Utils/EMTrackUtilities.h index 67830f4eee0..1609f2f5823 100644 --- a/PWGEM/Dilepton/Utils/EMTrackUtilities.h +++ b/PWGEM/Dilepton/Utils/EMTrackUtilities.h @@ -56,6 +56,30 @@ float fwdDcaXYinSigma(T const& track) } } //_______________________________________________________________________ +template +float sigmaPt(T const& track) +{ + return std::sqrt(track.c1Pt21Pt2()) / std::pow(track.signed1Pt(), 2); // pT resolution +} +//_______________________________________________________________________ +template +float sigmaPhi(T const& track) +{ + return std::sqrt(track.cSnpSnp()) / std::sqrt(1.f - std::pow(track.snp(), 2)); // phi resolution +} +//_______________________________________________________________________ +template +float sigmaLambda(T const& track) +{ + return std::sqrt(track.cTglTgl()) / (1.f + std::pow(track.tgl(), 2)); // theta resolution = lambda resolution. // lambda = pi/2 - theta. theta is polar angle. +} +//_______________________________________________________________________ +template +float sigmaP(T const& track) +{ + // p = pT x cosh(eta); + return std::sqrt(std::pow(std::cosh(track.eta()) * sigmaPt(track), 2) + std::pow(track.pt() * std::sinh(track.eta()) * std::cosh(track.eta()) * sigmaLambda(track), 2)); +} //_______________________________________________________________________ } // namespace o2::aod::pwgem::dilepton::utils::emtrackutil #endif // PWGEM_DILEPTON_UTILS_EMTRACKUTILITIES_H_ diff --git a/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt b/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt index a468376a761..7d58cb0cb7c 100644 --- a/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt +++ b/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt @@ -21,7 +21,7 @@ o2physics_add_dpl_workflow(skimmer-gamma-conversion-truthonlymc o2physics_add_dpl_workflow(photon-conversion-builder SOURCES photonconversionbuilder.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2Physics::AnalysisCore KFParticle::KFParticle + PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2Physics::AnalysisCore KFParticle::KFParticle O2Physics::TPCDriftManager COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(create-pcm diff --git a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx index 81346b201cf..226801fcc61 100644 --- a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx +++ b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx @@ -40,6 +40,7 @@ #include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" #include "Common/Core/TableHelper.h" +#include "Common/Core/TPCVDriftManager.h" #include "Tools/KFparticle/KFUtilities.h" @@ -84,6 +85,9 @@ struct PhotonConversionBuilder { // single track cuts Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable mincrossedrows{"mincrossedrows", 40, "min crossed rows"}; + Configurable moveTPCTracks{"moveTPCTracks", true, "Move TPC-only tracks under the collision assumption"}; + Configurable disableITSonlyTracks{"disableITSonlyTracks", false, "disable ITSonly tracks in V0 legs"}; + Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max chi2/NclsTPC"}; // default 4.0 + 1.0 Configurable maxchi2its{"maxchi2its", 6.0, "max chi2/NclsITS"}; // default 5.0 + 1.0 Configurable maxpt_itsonly{"maxpt_itsonly", 0.15, "max pT for ITSonly tracks at SV"}; @@ -128,6 +132,7 @@ struct PhotonConversionBuilder { Service ccdb; o2::base::MatLayerCylSet* lut = nullptr; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + o2::aod::common::TPCVDriftManager mVDriftMgr; HistogramRegistry registry{ "registry", @@ -188,10 +193,12 @@ struct PhotonConversionBuilder { lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); } - if (useMatCorrType == 1) + if (useMatCorrType == 1) { matCorr = o2::base::Propagator::MatCorrType::USEMatCorrTGeo; - if (useMatCorrType == 2) + } + if (useMatCorrType == 2) { matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + } } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -213,18 +220,19 @@ struct PhotonConversionBuilder { } auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) + o2::parameters::GRPObject* grpo = nullptr; + o2::parameters::GRPMagField* grpmag = nullptr; + if (!skipGRPOquery) { grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - if (grpo) { + } + if (grpo != nullptr) { o2::base::Propagator::initFieldFromGRP(grpo); // 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) { + if (grpmag == nullptr) { 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); @@ -239,8 +247,17 @@ struct PhotonConversionBuilder { o2::base::Propagator::Instance()->setMatLUT(lut); } /// Set magnetic field for KF vertexing - float magneticField = o2::base::Propagator::Instance()->getNominalBz(); + const float magneticField = o2::base::Propagator::Instance()->getNominalBz(); KFParticle::SetField(magneticField); + + mVDriftMgr.init(&ccdb->instance()); + } + + void updateCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + auto timestamp = bc.timestamp(); + + mVDriftMgr.update(timestamp); } std::pair> its_ib_Requirement = {0, {0, 1, 2}}; // no hit on 3 ITS ib layers. @@ -253,6 +270,10 @@ struct PhotonConversionBuilder { } } + if (disableITSonlyTracks && isITSonlyTrack(track)) { + return false; + } + if (track.x() > maxX) { return false; } @@ -344,8 +365,8 @@ struct PhotonConversionBuilder { return cospaRZ; } - template - void fillTrackTable(TTrack const& track, TKFParticle const& kfp, float dcaXY, float dcaZ) + template + void fillTrackTable(TTrack const& track, TShiftedTrack const& shiftedtrack, TKFParticle const& kfp, float dcaXY, float dcaZ) { v0legs(track.collisionId(), track.globalIndex(), track.sign(), kfp.GetPx(), kfp.GetPy(), kfp.GetPz(), dcaXY, dcaZ, @@ -353,16 +374,16 @@ struct PhotonConversionBuilder { track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap(), - track.x(), track.y(), track.z(), track.tgl()); + shiftedtrack.getX(), shiftedtrack.getY(), shiftedtrack.getZ(), shiftedtrack.getTgl()); } - template + template void fillV0Table(TV0 const& v0, const bool filltable) { // Get tracks - auto pos = v0.template posTrack_as(); - auto ele = v0.template negTrack_as(); - auto collision = v0.template collision_as(); // collision where this v0 belongs. + const auto& pos = v0.template posTrack_as(); + const auto& ele = v0.template negTrack_as(); + const auto& collision = v0.template collision_as(); // collision where this v0 belongs to. if (pos.sign() * ele.sign() > 0) { // reject same sign pair return; @@ -379,6 +400,7 @@ struct PhotonConversionBuilder { if (isITSonlyTrack(pos) && !ele.hasITS()) { return; } + if (isITSonlyTrack(ele) && !pos.hasITS()) { return; } @@ -386,20 +408,31 @@ struct PhotonConversionBuilder { if (!checkV0leg(pos) || !checkV0leg(ele)) { return; } + // LOGF(info, "v0.collisionId() = %d , v0.posTrackId() = %d , v0.negTrackId() = %d", v0.collisionId(), v0.posTrackId(), v0.negTrackId()); // Calculate DCA with respect to the collision associated to the v0, not individual tracks gpu::gpustd::array dcaInfo; auto pTrack = getTrackParCov(pos); - pTrack.setPID(o2::track::PID::Electron); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, pTrack, 2.f, matCorr, &dcaInfo); + if (moveTPCTracks && isTPConlyTrack(pos) && !mVDriftMgr.moveTPCTrack(collision, pos, pTrack)) { + LOGP(error, "failed correction for positive tpc track"); + return; + } + auto pTrackC = pTrack; + pTrackC.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, pTrackC, 2.f, matCorr, &dcaInfo); auto posdcaXY = dcaInfo[0]; auto posdcaZ = dcaInfo[1]; auto nTrack = getTrackParCov(ele); - nTrack.setPID(o2::track::PID::Electron); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, nTrack, 2.f, matCorr, &dcaInfo); + if (moveTPCTracks && isTPConlyTrack(ele) && !mVDriftMgr.moveTPCTrack(collision, ele, nTrack)) { + LOGP(error, "failed correction for negative tpc track"); + return; + } + auto nTrackC = nTrack; + nTrackC.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, nTrackC, 2.f, matCorr, &dcaInfo); auto eledcaXY = dcaInfo[0]; auto eledcaZ = dcaInfo[1]; @@ -408,17 +441,17 @@ struct PhotonConversionBuilder { } float xyz[3] = {0.f, 0.f, 0.f}; - Vtx_recalculation(o2::base::Propagator::Instance(), pos, ele, xyz, matCorr); + Vtx_recalculationParCov(o2::base::Propagator::Instance(), pTrack, nTrack, xyz, matCorr); float rxy_tmp = RecoDecay::sqrtSumOfSquares(xyz[0], xyz[1]); if (rxy_tmp > maxX + margin_r_tpc) { return; } - if (rxy_tmp < abs(xyz[2]) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-max_eta_v0))) - margin_z) { + if (rxy_tmp < fabs(xyz[2]) * std::tan(2 * std::atan(std::exp(-max_eta_v0))) - margin_z) { return; // RZ line cut } - KFPTrack kfp_track_pos = createKFPTrackFromTrack(pos); - KFPTrack kfp_track_ele = createKFPTrackFromTrack(ele); + KFPTrack kfp_track_pos = createKFPTrackFromTrackParCov(pTrack, pos.sign(), pos.tpcNClsFound(), pos.tpcChi2NCl()); + KFPTrack kfp_track_ele = createKFPTrackFromTrackParCov(nTrack, ele.sign(), ele.tpcNClsFound(), ele.tpcChi2NCl()); KFParticle kfp_pos(kfp_track_pos, -11); KFParticle kfp_ele(kfp_track_ele, 11); const KFParticle* GammaDaughters[2] = {&kfp_pos, &kfp_ele}; @@ -451,7 +484,7 @@ struct PhotonConversionBuilder { if (rxy > maxX + margin_r_tpc) { return; } - if (rxy < abs(gammaKF_DecayVtx.GetZ()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-max_eta_v0))) - margin_z) { + if (rxy < fabs(gammaKF_DecayVtx.GetZ()) * std::tan(2 * std::atan(std::exp(-max_eta_v0))) - margin_z) { return; // RZ line cut } if (rxy < min_v0radius) { @@ -460,30 +493,30 @@ struct PhotonConversionBuilder { if (!filltable) { if (isITSTPCTrack(pos) && isITSTPCTrack(ele)) { - registry.fill(HIST("V0/hRxy_minX_ITSTPC_ITSTPC"), std::min(pos.x(), ele.x()), std::min(pos.x(), ele.x()) - rxy); // trackiu.x() - rxy should be positive + registry.fill(HIST("V0/hRxy_minX_ITSTPC_ITSTPC"), std::min(pTrack.getX(), nTrack.getX()), std::min(pTrack.getX(), nTrack.getX()) - rxy); // trackiu.x() - rxy should be positive } else if (isITSonlyTrack(pos) && isITSonlyTrack(ele)) { - registry.fill(HIST("V0/hRxy_minX_ITSonly_ITSonly"), std::min(pos.x(), ele.x()), std::min(pos.x(), ele.x()) - rxy); // trackiu.x() - rxy should be positive + registry.fill(HIST("V0/hRxy_minX_ITSonly_ITSonly"), std::min(pTrack.getX(), nTrack.getX()), std::min(pTrack.getX(), nTrack.getX()) - rxy); // trackiu.x() - rxy should be positive } else if ((isITSTPCTrack(pos) && isITSonlyTrack(ele)) || (isITSTPCTrack(ele) && isITSonlyTrack(pos))) { - registry.fill(HIST("V0/hRxy_minX_ITSTPC_ITSonly"), std::min(pos.x(), ele.x()), std::min(pos.x(), ele.x()) - rxy); // trackiu.x() - rxy should be positive + registry.fill(HIST("V0/hRxy_minX_ITSTPC_ITSonly"), std::min(pTrack.getX(), nTrack.getX()), std::min(pTrack.getX(), nTrack.getX()) - rxy); // trackiu.x() - rxy should be positive } else if (isITSTPCTrack(pos) && !ele.hasITS()) { - registry.fill(HIST("V0/hRxy_minX_ITSTPC_TPC"), std::min(pos.x(), 83.f), std::min(pos.x(), 83.f) - rxy); // trackiu.x() - rxy should be positive + registry.fill(HIST("V0/hRxy_minX_ITSTPC_TPC"), std::min(pTrack.getX(), 83.f), std::min(pTrack.getX(), 83.f) - rxy); // trackiu.x() - rxy should be positive } else if (isITSTPCTrack(ele) && !pos.hasITS()) { - registry.fill(HIST("V0/hRxy_minX_ITSTPC_TPC"), std::min(ele.x(), 83.f), std::min(ele.x(), 83.f) - rxy); // trackiu.x() - rxy should be positive + registry.fill(HIST("V0/hRxy_minX_ITSTPC_TPC"), std::min(nTrack.getX(), 83.f), std::min(nTrack.getX(), 83.f) - rxy); // trackiu.x() - rxy should be positive } else { registry.fill(HIST("V0/hRxy_minX_TPC_TPC"), std::min(83.f, 83.f), std::min(83.f, 83.f) - rxy); // trackiu.x() - rxy should be positive } } if (pos.hasITS() && ele.hasITS()) { // ITSonly-ITSonly, ITSTPC-ITSTPC, ITSTPC-ITSonly - if (rxy > std::min(pos.x(), ele.x()) + margin_r_its) { + if (rxy > std::min(pTrack.getX(), nTrack.getX()) + margin_r_its) { return; } } else if (!pos.hasITS() && ele.hasITS()) { // ITSTPC-TPC - if (rxy > std::min(83.f, ele.x()) + margin_r_itstpc_tpc) { + if (rxy > std::min(83.f, nTrack.getX()) + margin_r_itstpc_tpc) { return; } } else if (pos.hasITS() && !ele.hasITS()) { // ITSTPC-TPC - if (rxy > std::min(pos.x(), 83.f) + margin_r_itstpc_tpc) { + if (rxy > std::min(pTrack.getX(), 83.f) + margin_r_itstpc_tpc) { return; } } else if (!pos.hasITS() && !ele.hasITS()) { // TPC-TPC @@ -596,7 +629,7 @@ struct PhotonConversionBuilder { registry.fill(HIST("V0/hPCA_CosPA"), cospa_kf, pca_kf); registry.fill(HIST("V0/hPCA_Rxy"), rxy, pca_kf); registry.fill(HIST("V0/hDCAxyz"), dca_xy_v0_to_pv, dca_z_v0_to_pv); - registry.fill(HIST("V0/hPCA_diffX"), pca_kf, std::min(pos.x(), ele.x()) - rxy); // trackiu.x() - rxy should be positive + registry.fill(HIST("V0/hPCA_diffX"), pca_kf, std::min(pTrack.getX(), nTrack.getX()) - rxy); // trackiu.x() - rxy should be positive float cospaXY_kf = cospaXY_KF(gammaKF_DecayVtx, KFPV); float cospaRZ_kf = cospaRZ_KF(gammaKF_DecayVtx, KFPV); @@ -616,8 +649,9 @@ struct PhotonConversionBuilder { for (auto& leg : {pos, ele}) { registry.fill(HIST("V0Leg/hdEdx_Pin"), leg.tpcInnerParam(), leg.tpcSignal()); registry.fill(HIST("V0Leg/hTPCNsigmaEl"), leg.tpcInnerParam(), leg.tpcNSigmaEl()); - registry.fill(HIST("V0Leg/hXZ"), leg.z(), leg.x()); } // end of leg loop + registry.fill(HIST("V0Leg/hXZ"), pTrack.getZ(), pTrack.getX()); + registry.fill(HIST("V0Leg/hXZ"), nTrack.getZ(), nTrack.getX()); registry.fill(HIST("V0Leg/hDCAxyz"), posdcaXY, posdcaZ); registry.fill(HIST("V0Leg/hDCAxyz"), eledcaXY, eledcaZ); @@ -632,8 +666,8 @@ struct PhotonConversionBuilder { v0_sv.M(), dca_xy_v0_to_pv, dca_z_v0_to_pv, cospa_kf, pca_kf, alpha, qt, chi2kf); - fillTrackTable(pos, kfp_pos_DecayVtx, posdcaXY, posdcaZ); // positive leg first - fillTrackTable(ele, kfp_ele_DecayVtx, eledcaXY, eledcaZ); // negative leg second + fillTrackTable(pos, pTrack, kfp_pos_DecayVtx, posdcaXY, posdcaZ); // positive leg first + fillTrackTable(ele, nTrack, kfp_ele_DecayVtx, eledcaXY, eledcaZ); // negative leg second } // end of fill table } @@ -647,7 +681,7 @@ struct PhotonConversionBuilder { template void build(TCollisions const& collisions, TV0s const& v0s, TTracks const&, TBCs const&) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { if constexpr (isMC) { if (!collision.has_mcCollision()) { continue; @@ -668,7 +702,7 @@ struct PhotonConversionBuilder { nv0_map[collision.globalIndex()] = 0; - auto bc = collision.template foundBC_as(); + const auto& bc = collision.template bc_as(); initCCDB(bc); registry.fill(HIST("hCollisionCounter"), 1); @@ -676,11 +710,13 @@ struct PhotonConversionBuilder { continue; } - auto v0s_per_coll = v0s.sliceBy(perCollision, collision.globalIndex()); + updateCCDB(bc); // delay update until is needed + + const auto& v0s_per_coll = v0s.sliceBy(perCollision, collision.globalIndex()); // LOGF(info, "n v0 = %d", v0s_per_coll.size()); - for (auto& v0 : v0s_per_coll) { + for (const auto& v0 : v0s_per_coll) { // LOGF(info, "collision.globalIndex() = %d, v0.globalIndex() = %d, v0.posTrackId() = %d, v0.negTrackId() = %d", collision.globalIndex(), v0.globalIndex(), v0.posTrackId() , v0.negTrackId()); - fillV0Table(v0, false); + fillV0Table(v0, false); } // end of v0 loop } // end of collision loop @@ -755,7 +791,7 @@ struct PhotonConversionBuilder { // LOGF(info, "collision_tmp.globalIndex() = %d, collision_tmp.neeuls() = %d, nv0_map = %d", collision_tmp.globalIndex(), collision_tmp.neeuls(), nv0_map[collision_tmp.globalIndex()]); } - fillV0Table(v0, true); + fillV0Table(v0, true); } // end of fullv0Id loop for (auto& collision : collisions) { diff --git a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx index a0adce9a15f..49f734c1a9d 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx @@ -122,7 +122,7 @@ struct PCMQC { // v0 info fRegistry.add("V0/hPt", "pT;p_{T,#gamma} (GeV/c)", kTH1F, {{2000, 0.0f, 20}}, false); - fRegistry.add("V0/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{36, 0, 2 * M_PI}, {20, -1.0f, 1.0f}}, false); + fRegistry.add("V0/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{90, 0, 2 * M_PI}, {40, -1.0f, 1.0f}}, false); fRegistry.add("V0/hRadius", "V0Radius; radius in Z (cm);radius in XY (cm)", kTH2F, {{200, -100, 100}, {200, 0.0f, 100.0f}}, false); fRegistry.add("V0/hCosPA", "V0CosPA;cosine pointing angle", kTH1F, {{100, 0.9f, 1.0f}}, false); fRegistry.add("V0/hCosPA_Rxy", "cos PA vs. R_{xy};R_{xy} (cm);cosine pointing angle", kTH2F, {{200, 0.f, 100.f}, {100, 0.9f, 1.0f}}, false); @@ -143,7 +143,7 @@ struct PCMQC { // v0leg info fRegistry.add("V0Leg/hPt", "pT;p_{T,e} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); fRegistry.add("V0Leg/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{1000, -50, 50}}, false); - fRegistry.add("V0Leg/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {40, -2.0f, 2.0f}}, false); + fRegistry.add("V0Leg/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{90, 0, 2 * M_PI}, {40, -1.0f, 1.0f}}, false); fRegistry.add("V0Leg/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -50.0f, 50.0f}, {200, -50.0f, 50.0f}}, false); fRegistry.add("V0Leg/hNclsTPC", "number of TPC clusters", kTH1F, {{161, -0.5, 160.5}}, false); fRegistry.add("V0Leg/hNcrTPC", "number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, false); @@ -156,10 +156,10 @@ struct PCMQC { fRegistry.add("V0Leg/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); fRegistry.add("V0Leg/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); fRegistry.add("V0Leg/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); - fRegistry.add("V0Leg/hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", kTH1F, {{32, 0, 16}}, false); - fRegistry.add("V0Leg/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {100, -50, 50}}, false); + fRegistry.add("V0Leg/hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {160, 0, 16}}, false); + fRegistry.add("V0Leg/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {80, -20, 20}}, false); fRegistry.add("V0Leg/hZX", "Z vs. X;Z (cm);X (cm)", kTH2F, {{200, -100, 100}, {100, 0, 100}}, false); - fRegistry.add("V0Leg/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {100, -50, 50}}, false); + fRegistry.add("V0Leg/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {80, -20, 20}}, false); } void DefineEMEventCut() @@ -309,7 +309,9 @@ struct PCMQC { fRegistry.fill(HIST("V0Leg/hChi2TPC"), leg.tpcChi2NCl()); fRegistry.fill(HIST("V0Leg/hChi2ITS"), leg.itsChi2NCl()); fRegistry.fill(HIST("V0Leg/hITSClusterMap"), leg.itsClusterMap()); - fRegistry.fill(HIST("V0Leg/hMeanClusterSizeITS"), leg.meanClusterSizeITS() * std::cos(std::atan(leg.tgl()))); + if (leg.hasITS()) { + fRegistry.fill(HIST("V0Leg/hMeanClusterSizeITS"), leg.p(), leg.meanClusterSizeITS() * std::cos(std::atan(leg.tgl()))); + } fRegistry.fill(HIST("V0Leg/hTPCdEdx"), leg.tpcInnerParam(), leg.tpcSignal()); fRegistry.fill(HIST("V0Leg/hTPCNsigmaEl"), leg.tpcInnerParam(), leg.tpcNSigmaEl()); fRegistry.fill(HIST("V0Leg/hTPCNsigmaPi"), leg.tpcInnerParam(), leg.tpcNSigmaPi()); @@ -344,6 +346,7 @@ struct PCMQC { for (auto& v0 : v0photons_coll) { auto pos = v0.posTrack_as(); auto ele = v0.negTrack_as(); + if (!fV0PhotonCut.IsSelected(v0)) { continue; } @@ -355,7 +358,7 @@ struct PCMQC { } // end of v0 loop fRegistry.fill(HIST("V0/hNgamma"), nv0); } // end of collision loop - } // end of process + } // end of process void processDummy(MyCollisions const&) {} diff --git a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx index 4f7dc79ce23..279c0a57c80 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx @@ -164,7 +164,7 @@ struct PCMQCMC { // v0 info fRegistry.add("V0/primary/hPt", "pT;p_{T,#gamma} (GeV/c)", kTH1F, {{2000, 0.0f, 20}}, false); - fRegistry.add("V0/primary/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{36, 0, 2 * M_PI}, {20, -1.0f, 1.0f}}, false); + fRegistry.add("V0/primary/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{90, 0, 2 * M_PI}, {40, -1.0f, 1.0f}}, false); fRegistry.add("V0/primary/hRadius", "V0Radius; radius in Z (cm);radius in XY (cm)", kTH2F, {{200, -100, 100}, {200, 0.0f, 100.0f}}, false); fRegistry.add("V0/primary/hCosPA", "V0CosPA;cosine pointing angle", kTH1F, {{100, 0.9f, 1.0f}}, false); fRegistry.add("V0/primary/hCosPA_Rxy", "cos PA vs. R_{xy};R_{xy} (cm);cosine pointing angle", kTH2F, {{200, 0.f, 100.f}, {100, 0.9f, 1.0f}}, false); @@ -195,7 +195,7 @@ struct PCMQCMC { // v0leg info fRegistry.add("V0Leg/primary/hPt", "pT;p_{T,e} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); fRegistry.add("V0Leg/primary/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{1000, -50, 50}}, false); - fRegistry.add("V0Leg/primary/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {40, -2.0f, 2.0f}}, false); + fRegistry.add("V0Leg/primary/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{90, 0, 2 * M_PI}, {40, -3.0f, 1.0f}}, false); fRegistry.add("V0Leg/primary/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -50.0f, 50.0f}, {200, -50.0f, 50.0f}}, false); fRegistry.add("V0Leg/primary/hNclsTPC", "number of TPC clusters", kTH1F, {{161, -0.5, 160.5}}, false); fRegistry.add("V0Leg/primary/hNcrTPC", "number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, false); @@ -208,10 +208,10 @@ struct PCMQCMC { fRegistry.add("V0Leg/primary/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); fRegistry.add("V0Leg/primary/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); fRegistry.add("V0Leg/primary/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); - fRegistry.add("V0Leg/primary/hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", kTH1F, {{32, 0, 16}}, false); - fRegistry.add("V0Leg/primary/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {100, -50, 50}}, false); + fRegistry.add("V0Leg/primary/hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {160, 0, 16}}, false); + fRegistry.add("V0Leg/primary/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {40, -20, 20}}, false); fRegistry.add("V0Leg/primary/hZX", "Z vs. X;Z (cm);X (cm)", kTH2F, {{200, -100, 100}, {100, 0, 100}}, false); - fRegistry.add("V0Leg/primary/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {100, -50, 50}}, false); + fRegistry.add("V0Leg/primary/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {40, -20, 20}}, false); fRegistry.add("V0Leg/primary/hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{1000, 0, 10}, {400, -1.0f, 1.0f}}, true); fRegistry.add("V0Leg/primary/hPtGen_DeltaEta", "electron #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{1000, 0, 10}, {400, -1.0f, 1.0f}}, true); fRegistry.add("V0Leg/primary/hPtGen_DeltaPhi", "electron #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{1000, 0, 10}, {400, -1.0f, 1.0f}}, true); @@ -374,7 +374,9 @@ struct PCMQCMC { fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hChi2TPC"), leg.tpcChi2NCl()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hChi2ITS"), leg.itsChi2NCl()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hITSClusterMap"), leg.itsClusterMap()); - fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hMeanClusterSizeITS"), leg.meanClusterSizeITS() * std::cos(std::atan(leg.tgl()))); + if (leg.hasITS()) { + fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hMeanClusterSizeITS"), leg.p(), leg.meanClusterSizeITS() * std::cos(std::atan(leg.tgl()))); + } fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hTPCdEdx"), leg.tpcInnerParam(), leg.tpcSignal()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hTPCNsigmaEl"), leg.tpcInnerParam(), leg.tpcNSigmaEl()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hTPCNsigmaPi"), leg.tpcInnerParam(), leg.tpcNSigmaPi()); @@ -452,7 +454,7 @@ struct PCMQCMC { fRegistry.fill(HIST("V0/fromWD/hNgamma"), ng_wd); fRegistry.fill(HIST("V0/fromHS/hNgamma"), ng_hs); } // end of collision loop - } // end of process + } // end of process template void fillBinnedData(TBinnedData const& binned_data, const float weight = 1.f) @@ -516,7 +518,7 @@ struct PCMQCMC { fRegistry.fill(HIST("Generated/hPhotonPhivsRxy"), daughter.phi(), rxy_gen_e); } } // end of mctrack loop per collision - } // end of collision loop + } // end of collision loop } void processDummy(MyCollisions const&) {} diff --git a/PWGEM/PhotonMeson/Utils/PCMUtilities.h b/PWGEM/PhotonMeson/Utils/PCMUtilities.h index 38492dae9e6..9530fa03c4f 100644 --- a/PWGEM/PhotonMeson/Utils/PCMUtilities.h +++ b/PWGEM/PhotonMeson/Utils/PCMUtilities.h @@ -47,18 +47,11 @@ inline float v0_qt(float pxpos, float pypos, float pzpos, float pxneg, float pyn return std::sqrt(RecoDecay::p2(pxneg, pyneg, pzneg) - dp * dp / momTot); // qt of v0 } //_______________________________________________________________________ -template -inline void Vtx_recalculation(o2::base::Propagator* prop, T1 lTrackPos, T2 lTrackNeg, float xyz[3], o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE) +template +inline void Vtx_recalculationParCov(o2::base::Propagator* prop, const o2::track::TrackParametrizationWithError& trackPosInformation, const o2::track::TrackParametrizationWithError& trackNegInformation, float xyz[3], o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE) { float bz = prop->getNominalBz(); - //******************************************************* - - o2::track::TrackParametrizationWithError trackPosInformation = getTrackParCov(lTrackPos); // first get an object that stores Track information (positive) - o2::track::TrackParametrizationWithError trackNegInformation = getTrackParCov(lTrackNeg); // first get an object that stores Track information (negative) - trackPosInformation.setPID(o2::track::PID::Electron); - trackNegInformation.setPID(o2::track::PID::Electron); - o2::track::TrackAuxPar helixPos(trackPosInformation, bz); // This object is a descendant of a CircleXY and stores cirlce information with respect to the magnetic field. This object uses functions and information of the o2::track::TrackParametrizationWithError object (positive) o2::track::TrackAuxPar helixNeg(trackNegInformation, bz); // This object is a descendant of a CircleXY and stores cirlce information with respect to the magnetic field. This object uses functions and information of the o2::track::TrackParametrizationWithError object (negative) @@ -66,10 +59,8 @@ inline void Vtx_recalculation(o2::base::Propagator* prop, T1 lTrackPos, T2 lTrac xyz[1] = (helixPos.yC * helixNeg.rC + helixNeg.yC * helixPos.rC) / (helixPos.rC + helixNeg.rC); // If this calculation doesn't work check if the rotateZ function, because the "documentation" says I get global coordinates but maybe i don't. // I am unsure about the Z calculation but this is how it is done in AliPhysics as far as I understand - o2::track::TrackParametrizationWithError trackPosInformationCopy = o2::track::TrackParametrizationWithError(trackPosInformation); - o2::track::TrackParametrizationWithError trackNegInformationCopy = o2::track::TrackParametrizationWithError(trackNegInformation); - trackPosInformationCopy.setPID(o2::track::PID::Electron); - trackNegInformationCopy.setPID(o2::track::PID::Electron); + auto trackPosInformationCopy = trackPosInformation; + auto trackNegInformationCopy = trackNegInformation; // I think this calculation gets the closest point on the track to the conversion point // This alpha is a different alpha than the usual alpha and I think it is the angle between X axis and conversion point @@ -104,5 +95,13 @@ inline void Vtx_recalculation(o2::base::Propagator* prop, T1 lTrackPos, T2 lTrac xyz[2] = (trackPosInformationCopy.getZ() * helixNeg.rC + trackNegInformationCopy.getZ() * helixPos.rC) / (helixPos.rC + helixNeg.rC); } //_______________________________________________________________________ -//_______________________________________________________________________ +template +inline void Vtx_recalculation(o2::base::Propagator* prop, T1 lTrackPos, T2 lTrackNeg, float xyz[3], o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE) +{ + // o2::track::TrackParametrizationWithError = TrackParCov, I use the full version to have control over the data type + o2::track::TrackParametrizationWithError trackPosInformation = getTrackParCov(lTrackPos); // first get an object that stores Track information (positive) + o2::track::TrackParametrizationWithError trackNegInformation = getTrackParCov(lTrackNeg); // first get an object that stores Track information (negative) + + Vtx_recalculationParCov(prop, trackPosInformation, trackNegInformation, xyz, matCorr); +} #endif // PWGEM_PHOTONMESON_UTILS_PCMUTILITIES_H_ diff --git a/PWGEM/Tasks/phosElId.cxx b/PWGEM/Tasks/phosElId.cxx index 2423992f953..327061dbfbc 100644 --- a/PWGEM/Tasks/phosElId.cxx +++ b/PWGEM/Tasks/phosElId.cxx @@ -101,21 +101,21 @@ struct phosElId { Configurable mEpmin{"mEpmin", -1., "Min for E/p histograms"}; Configurable mEpmax{"mEpmax", 3., "Max for E/p histograms"}; - Configurable> pSigma_dz{"pSigma_dz", {20., 0.76, 6.6, 3.6, 0.1}, "parameters for sigma dz function"}; - Configurable> pSigma_dx{"pSigma_dx", {3, 2.3, 3.1}, "parameters for sigma dx function"}; + Configurable> pSigma_dz{"pSigma_dz", {0.642, 0., 1.77, 2.725, 0.}, "parameters for sigma dz function"}; + Configurable> pSigma_dx{"pSigma_dx", {2.17769, 1.60275, 2.24136}, "parameters for sigma dx function"}; - Configurable> pPhosShiftZ{"pPhosShiftZ", {4.5, 3., 2., 2.}, "Phos coordinate centering Z per module"}; - Configurable> pPhosShiftX{"pPhosShiftX", {1.99, -0.63, -1.55, -1.63}, "Phos coordinate centering X per module"}; + Configurable> pPhosShiftZ{"pPhosShiftZ", {4.78838, 2.75138, 1.40825, 2.28735}, "Phos coordinate centering Z per module"}; + Configurable> pPhosShiftX{"pPhosShiftX", {2.158702, -1.526772, -0.814658, -1.852678}, "Phos coordinate centering X per module"}; - Configurable> pMean_dx_pos_mod1{"pMean_dx_pos_mod1", {-9.57, -0.47, 1.04}, "parameters for mean dx function on module 1 for positive tracks"}; - Configurable> pMean_dx_pos_mod2{"pMean_dx_pos_mod2", {-12.24, -0.18, 1.59}, "parameters for mean dx function on module 2 for positive tracks"}; - Configurable> pMean_dx_pos_mod3{"pMean_dx_pos_mod3", {-5.73, -0.58, 1.13}, "parameters for mean dx function on module 3 for positive tracks"}; - Configurable> pMean_dx_pos_mod4{"pMean_dx_pos_mod4", {-5.14, -0.67, 1.05}, "parameters for mean dx function on module 4 for positive tracks"}; + Configurable> pMean_dx_pos_mod1{"pMean_dx_pos_mod1", {-10.57, -0.42, 1.06}, "parameters for mean dx function on module 1 for positive tracks"}; + Configurable> pMean_dx_pos_mod2{"pMean_dx_pos_mod2", {-8.1, -0.42, 1.14}, "parameters for mean dx function on module 2 for positive tracks"}; + Configurable> pMean_dx_pos_mod3{"pMean_dx_pos_mod3", {-8.34, -0.42, 1.04}, "parameters for mean dx function on module 3 for positive tracks"}; + Configurable> pMean_dx_pos_mod4{"pMean_dx_pos_mod4", {-7.38, -0.42, 1.17}, "parameters for mean dx function on module 4 for positive tracks"}; - Configurable> pMean_dx_neg_mod1{"pMean_dx_neg_mod1", {10.29, -0.42, 1.12}, "parameters for mean dx function on module 1 for negative tracks"}; - Configurable> pMean_dx_neg_mod2{"pMean_dx_neg_mod2", {8.24, -0.42, 1.31}, "parameters for mean dx function on module 2 for negative tracks"}; - Configurable> pMean_dx_neg_mod3{"pMean_dx_neg_mod3", {11.83, -0.17, 1.71}, "parameters for mean dx function on module 3 for negative tracks"}; - Configurable> pMean_dx_neg_mod4{"pMean_dx_neg_mod4", {84.96, 0.79, 2.83}, "parameters for mean dx function on module 4 for negative tracks"}; + Configurable> pMean_dx_neg_mod1{"pMean_dx_neg_mod1", {9.92, -0.42, 1.29}, "parameters for mean dx function on module 1 for negative tracks"}; + Configurable> pMean_dx_neg_mod2{"pMean_dx_neg_mod2", {7.82, -0.4, 1.34}, "parameters for mean dx function on module 2 for negative tracks"}; + Configurable> pMean_dx_neg_mod3{"pMean_dx_neg_mod3", {8.45, -0.33, 1.5}, "parameters for mean dx function on module 3 for negative tracks"}; + Configurable> pMean_dx_neg_mod4{"pMean_dx_neg_mod4", {7.5, -0.42, 1.25}, "parameters for mean dx function on module 4 for negative tracks"}; Configurable cfgEtaMax{"cfgEtaMax", {0.8f}, "eta ranges"}; Configurable cfgPtMin{"cfgPtMin", {0.2f}, "pt min"}; @@ -248,18 +248,6 @@ struct phosElId { mHistManager.add("hCluE_ncells_mod", "Cluster energy spectrum per module", HistType::kTH3F, {axisE, axisCells, axisModes}); mHistManager.add("hCluXZ_mod", "Local cluster X Z per module", HistType::kTH3F, {axisX, axisZ, axisModes}); - mHistManager.add("hCluE_v_pt_disp", "Cluster energy vs p | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); - mHistManager.add("hCluE_v_pt_1sigma", "Cluster energy vs p within trackmatch 1sigma", HistType::kTH3F, {axisE, axisPt, axisModes}); - mHistManager.add("hCluE_v_pt_1sigma_disp", "Cluster energy vs p within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); - mHistManager.add("hCluE_v_pt_2sigma", "Cluster energy vs p within trackmatch 2sigma", HistType::kTH3F, {axisE, axisPt, axisModes}); - mHistManager.add("hCluE_v_pt_2sigma_disp", "Cluster energy vs p within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); - - mHistManager.add("hEp_v_pt_disp", "E/p ratio vs p | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); - mHistManager.add("hEp_v_pt_1sigma", "E/p ratio vs p within trackmatch 1sigma", HistType::kTH3F, {axisEp, axisPt, axisModes}); - mHistManager.add("hEp_v_pt_1sigma_disp", "E/p ratio vs p within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); - mHistManager.add("hEp_v_pt_2sigma", "E/p ratio vs p within trackmatch 2sigma", HistType::kTH3F, {axisEp, axisPt, axisModes}); - mHistManager.add("hEp_v_pt_2sigma_disp", "E/p ratio vs p within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); - mHistManager.add("hdZpmod", "dz,p_{tr},module", HistType::kTH3F, {axisdZ, axisPt, axisModes}); mHistManager.add("hdZpmod_pos", "dz,p_{tr},module positive tracks", HistType::kTH3F, {axisdZ, axisPt, axisModes}); mHistManager.add("hdZpmod_neg", "dz,p_{tr},module negative tracks", HistType::kTH3F, {axisdZ, axisPt, axisModes}); @@ -267,18 +255,42 @@ struct phosElId { mHistManager.add("hdXpmod_pos", "dx,p_{tr},module positive tracks", HistType::kTH3F, {axisdX, axisPt, axisModes}); mHistManager.add("hdXpmod_neg", "dx,p_{tr},module negative tracks", HistType::kTH3F, {axisdX, axisPt, axisModes}); + mHistManager.add("hCluE_v_pt_disp", "Cluster energy vs p | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); + mHistManager.add("hCluE_v_pt_1sigma", "Cluster energy vs p within trackmatch 1sigma", HistType::kTH3F, {axisE, axisPt, axisModes}); + mHistManager.add("hCluE_v_pt_1sigma_disp", "Cluster energy vs p within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); + mHistManager.add("hCluE_v_pt_2sigma", "Cluster energy vs p within trackmatch 2sigma", HistType::kTH3F, {axisE, axisPt, axisModes}); + mHistManager.add("hCluE_v_pt_2sigma_disp", "Cluster energy vs p within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); + mHistManager.add("hCluE_v_pt_disp_TPC", "Cluster energy vs p | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); mHistManager.add("hCluE_v_pt_1sigma_TPC", "Cluster energy vs p within trackmatch 1sigma", HistType::kTH3F, {axisE, axisPt, axisModes}); mHistManager.add("hCluE_v_pt_1sigma_disp_TPC", "Cluster energy vs p within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); mHistManager.add("hCluE_v_pt_2sigma_TPC", "Cluster energy vs p within trackmatch 2sigma", HistType::kTH3F, {axisE, axisPt, axisModes}); mHistManager.add("hCluE_v_pt_2sigma_disp_TPC", "Cluster energy vs p within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisE, axisPt, axisModes}); + mHistManager.add("hEp_v_pt_disp", "E/p ratio vs p | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); + mHistManager.add("hEp_v_pt_1sigma", "E/p ratio vs p within trackmatch 1sigma", HistType::kTH3F, {axisEp, axisPt, axisModes}); + mHistManager.add("hEp_v_pt_1sigma_disp", "E/p ratio vs p within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); + mHistManager.add("hEp_v_pt_2sigma", "E/p ratio vs p within trackmatch 2sigma", HistType::kTH3F, {axisEp, axisPt, axisModes}); + mHistManager.add("hEp_v_pt_2sigma_disp", "E/p ratio vs p within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); + + mHistManager.add("hEp_v_E_disp", "E/p ratio vs cluster E | OK dispersion", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_1sigma", "E/p ratio vs cluster E within trackmatch 1sigma", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_1sigma_disp", "E/p ratio vs cluster E within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_2sigma", "E/p ratio vs cluster E within trackmatch 2sigma", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_2sigma_disp", "E/p ratio vs cluster E within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_pt_disp_TPC", "E/p ratio vs p | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); mHistManager.add("hEp_v_pt_1sigma_TPC", "E/p ratio vs p within trackmatch 1sigma", HistType::kTH3F, {axisEp, axisPt, axisModes}); mHistManager.add("hEp_v_pt_1sigma_disp_TPC", "E/p ratio vs p within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); mHistManager.add("hEp_v_pt_2sigma_TPC", "E/p ratio vs p within trackmatch 2sigma", HistType::kTH3F, {axisEp, axisPt, axisModes}); mHistManager.add("hEp_v_pt_2sigma_disp_TPC", "E/p ratio vs p within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisEp, axisPt, axisModes}); + mHistManager.add("hEp_v_E_disp_TPC", "E/p ratio vs cluster E | OK dispersion", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_1sigma_TPC", "E/p ratio vs cluster E within trackmatch 1sigma", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_1sigma_disp_TPC", "E/p ratio vs cluster E within trackmatch 1sigma | OK dispersion", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_2sigma_TPC", "E/p ratio vs cluster E within trackmatch 2sigma", HistType::kTH3F, {axisEp, axisE, axisModes}); + mHistManager.add("hEp_v_E_2sigma_disp_TPC", "E/p ratio vs cluster E within trackmatch 2sigma | OK dispersion", HistType::kTH3F, {axisEp, axisE, axisModes}); + geomPHOS = std::make_unique("PHOS"); fSigma_dz = new TF1("fSigma_dz", "[0]/(x+[1])^[2]+pol1(3)", 0.3, 10); fSigma_dz->SetParameters(parameters_sigma_dz.at(0), parameters_sigma_dz.at(1), parameters_sigma_dz.at(2), parameters_sigma_dz.at(3), parameters_sigma_dz.at(4)); @@ -307,7 +319,7 @@ struct phosElId { } void process(soa::Join::iterator const& collision, aod::CaloClusters& clusters, - soa::Filtered& tracks, + soa::Filtered const& tracks, aod::BCsWithTimestamps const&) { auto bc = collision.bc_as(); @@ -415,41 +427,51 @@ struct phosElId { if (isDispOK) { mHistManager.fill(HIST("hCluE_v_pt_disp"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_disp"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_disp"), Ep, cluE, module); if (isElectron) { mHistManager.fill(HIST("hCluE_v_pt_disp_TPC"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_disp_TPC"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_disp_TPC"), Ep, cluE, module); } } if (!isWithin2Sigma(module, trackPT, dZ, dX)) continue; mHistManager.fill(HIST("hCluE_v_pt_2sigma"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_2sigma"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_2sigma"), Ep, cluE, module); if (isElectron) { mHistManager.fill(HIST("hCluE_v_pt_2sigma_TPC"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_2sigma_TPC"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_2sigma_TPC"), Ep, cluE, module); } if (isDispOK) { mHistManager.fill(HIST("hCluE_v_pt_2sigma_disp"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_2sigma_disp"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_2sigma_disp"), Ep, cluE, module); if (isElectron) { mHistManager.fill(HIST("hCluE_v_pt_2sigma_disp_TPC"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_2sigma_disp_TPC"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_2sigma_disp_TPC"), Ep, cluE, module); } phosMatch(collision.index(), clu.index(), track.index()); } if (isWithin1Sigma(module, trackPT, dZ, dX)) { mHistManager.fill(HIST("hCluE_v_pt_1sigma"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_1sigma"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_1sigma"), Ep, cluE, module); if (isElectron) { mHistManager.fill(HIST("hCluE_v_pt_1sigma_TPC"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_1sigma_TPC"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_1sigma_TPC"), Ep, cluE, module); } if (isDispOK) { mHistManager.fill(HIST("hCluE_v_pt_1sigma_disp"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_1sigma_disp"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_1sigma_disp"), Ep, cluE, module); if (isElectron) { mHistManager.fill(HIST("hCluE_v_pt_1sigma_disp_TPC"), cluE, trackPT, module); mHistManager.fill(HIST("hEp_v_pt_1sigma_disp_TPC"), Ep, trackPT, module); + mHistManager.fill(HIST("hEp_v_E_1sigma_disp_TPC"), Ep, cluE, module); } } } @@ -669,13 +691,26 @@ struct massSpectra { const AxisSpec axisCounter{1, 0, +1, ""}, axisPt{momentum_binning, "p_{T} (GeV/c)"}, + axisE{200, 0, 10, "E (GeV)", "E (GeV)"}, axisMassSpectrum{4000, 0, 4, "M (GeV/c^{2})", "Mass e^{+}e^{-} (GeV/c^{2})"}; mHistManager.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); mHistManager.add("TVXinPHOSCounter", "TVXinPHOSCounter", kTH1F, {axisCounter}); - mHistManager.add("h_eh_mass_spectra", "Mass e^{#pm}h^{#mp} vs momentum e^{#pm}h^{#mp}", HistType::kTH2F, {axisMassSpectrum, axisPt}); - mHistManager.add("h_ee_mass_spectra", "Mass e^{#pm}e^{#mp} vs momentum e^{#pm}e^{#mp}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_eh_pp_mass_spectra_v_Pt", "Mass e^{+}h^{+} vs momentum e^{+}h^{+}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_ee_pp_mass_spectra_v_Pt", "Mass e^{+}e^{+} vs momentum e^{+}e^{+}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_eh_mm_mass_spectra_v_Pt", "Mass e^{-}h^{-} vs momentum e^{-}h^{-}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_ee_mm_mass_spectra_v_Pt", "Mass e^{-}e^{-} vs momentum e^{-}e^{-}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + + mHistManager.add("h_eh_pp_mass_spectra_v_E", "Mass e^{+}h^{+} vs cluster E e^{+}h^{+}", HistType::kTH2F, {axisMassSpectrum, axisE}); + mHistManager.add("h_ee_pp_mass_spectra_v_E", "Mass e^{+}e^{+} vs cluster E e^{+}e^{+}", HistType::kTH2F, {axisMassSpectrum, axisE}); + mHistManager.add("h_eh_mm_mass_spectra_v_E", "Mass e^{-}h^{-} vs cluster E e^{-}h^{-}", HistType::kTH2F, {axisMassSpectrum, axisE}); + mHistManager.add("h_ee_mm_mass_spectra_v_E", "Mass e^{-}e^{-} vs cluster E e^{-}e^{-}", HistType::kTH2F, {axisMassSpectrum, axisE}); + + mHistManager.add("h_eh_mp_mass_spectra_v_Pt", "Mass e^{#pm}h^{#mp} vs momentum e^{#pm}h^{#mp}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_ee_mp_mass_spectra_v_Pt", "Mass e^{#pm}e^{#mp} vs momentum e^{#pm}e^{#mp}", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_eh_mp_mass_spectra_v_E", "Mass e^{#pm}h^{#mp} vs cluster E e^{#pm}h^{#mp}", HistType::kTH2F, {axisMassSpectrum, axisE}); + mHistManager.add("h_ee_mp_mass_spectra_v_E", "Mass e^{#pm}e^{#mp} vs cluster E e^{#pm}e^{#mp}", HistType::kTH2F, {axisMassSpectrum, axisE}); geomPHOS = std::make_unique("PHOS"); @@ -756,18 +791,38 @@ struct massSpectra { if (TPCel.index() >= track2.index()) break; - if (TPCel.sign() == track2.sign()) - continue; - float mass_2tracks = 0, mom_2tracks = 0; + float mass_2tracks = 0, mom_2tracks = 0, cluE = clust2.e(); TLorentzVector P1, P2; P1.SetPxPyPzE(TPCel.px(), TPCel.py(), TPCel.pz(), TPCel.energy(0)); P2.SetPxPyPzE(track2.px(), track2.py(), track2.pz(), track2.energy(0)); mom_2tracks = (P1 + P2).Pt(); mass_2tracks = (P1 + P2).M(); - mHistManager.fill(HIST("h_eh_mass_spectra"), mass_2tracks, mom_2tracks); - - if (fabs(clust2.e() / track2.p() - 1) < 2 * fEp_sigma_phos->Eval(mom_2tracks)) { - mHistManager.fill(HIST("h_ee_mass_spectra"), mass_2tracks, mom_2tracks); + bool posTrack = (TPCel.sign() > 0 && bz > 0) || (TPCel.sign() < 0 && bz < 0); + bool elCandidate = (fabs(clust2.e() / track2.p() - 1) < 2 * fEp_sigma_phos->Eval(mom_2tracks)); + + if (TPCel.sign() == track2.sign()) { + if (posTrack) { + mHistManager.fill(HIST("h_eh_pp_mass_spectra_v_Pt"), mass_2tracks, mom_2tracks); + mHistManager.fill(HIST("h_eh_pp_mass_spectra_v_E"), mass_2tracks, cluE); + if (elCandidate) { + mHistManager.fill(HIST("h_ee_pp_mass_spectra_v_Pt"), mass_2tracks, mom_2tracks); + mHistManager.fill(HIST("h_ee_pp_mass_spectra_v_E"), mass_2tracks, cluE); + } + } else { + mHistManager.fill(HIST("h_eh_mm_mass_spectra_v_Pt"), mass_2tracks, mom_2tracks); + mHistManager.fill(HIST("h_eh_mm_mass_spectra_v_E"), mass_2tracks, cluE); + if (elCandidate) { + mHistManager.fill(HIST("h_ee_mm_mass_spectra_v_Pt"), mass_2tracks, mom_2tracks); + mHistManager.fill(HIST("h_ee_mm_mass_spectra_v_E"), mass_2tracks, cluE); + } + } + } else { + mHistManager.fill(HIST("h_eh_mp_mass_spectra_v_Pt"), mass_2tracks, mom_2tracks); + mHistManager.fill(HIST("h_eh_mp_mass_spectra_v_E"), mass_2tracks, cluE); + if (elCandidate) { + mHistManager.fill(HIST("h_ee_mp_mass_spectra_v_Pt"), mass_2tracks, mom_2tracks); + mHistManager.fill(HIST("h_ee_mp_mass_spectra_v_E"), mass_2tracks, cluE); + } } } } // end of double loop @@ -814,7 +869,8 @@ struct tpcElIdMassSpectrum { Filter tpcPr_rej = (aod::pidtpc::tpcNSigmaPr < cfgTPCNSigmaPrMin) || (aod::pidtpc::tpcNSigmaPr > cfgTPCNSigmaPrMax); Service ccdb; - std::unique_ptr geomPHOS; + double bz{0.}; // magnetic field + int runNumber{0}; HistogramRegistry mHistManager{"tpcElIdHistograms"}; @@ -843,9 +899,13 @@ struct tpcElIdMassSpectrum { mHistManager.add("h_TPCee_MS_mm", "Mass e^{-}e^{-} vs momentum e^{-}e^{-} (from TPC candidates) vs pair pt", HistType::kTH2F, {axisMassSpectrum, axisPt}); mHistManager.add("h_TPCee_MS_pp", "Mass e^{+}e^{+} vs momentum e^{+}e^{+} (from TPC candidates) vs pair pt", HistType::kTH2F, {axisMassSpectrum, axisPt}); - mHistManager.add("h_TPCee_MS_mp_phosRange", "Mass e^{#pm}e^{#mp} vs momentum e^{#pm}e^{#mp} (from TPC candidates) vs pair pt with one e in phosRange", HistType::kTH2F, {axisMassSpectrum, axisPt}); - mHistManager.add("h_TPCee_MS_mm_phosRange", "Mass e^{-}e^{-} vs momentum e^{-}e^{-} (from TPC candidates) vs pair pt with one e in phosRange", HistType::kTH2F, {axisMassSpectrum, axisPt}); - mHistManager.add("h_TPCee_MS_pp_phosRange", "Mass e^{+}e^{+} vs momentum e^{+}e^{+} (from TPC candidates) vs pair pt with one e in phosRange", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_TPCee_MS_mp_phosRange", "Mass e^{#pm}e^{#mp} vs momentum e^{#pm}e^{#mp} (from TPC candidates) vs pair pt with one e in phos acceptance range", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_TPCee_MS_mm_phosRange", "Mass e^{-}e^{-} vs momentum e^{-}e^{-} (from TPC candidates) vs pair pt with one e in phos acceptance range", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_TPCee_MS_pp_phosRange", "Mass e^{+}e^{+} vs momentum e^{+}e^{+} (from TPC candidates) vs pair pt with one e in phos acceptance range", HistType::kTH2F, {axisMassSpectrum, axisPt}); + + mHistManager.add("h_TPCee_MS_mp_phosRange_kTVXinPHOS", "Mass e^{#pm}e^{#mp} vs momentum e^{#pm}e^{#mp} (from TPC candidates) vs pair pt with one e in phos acceptance range", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_TPCee_MS_mm_phosRange_kTVXinPHOS", "Mass e^{-}e^{-} vs momentum e^{-}e^{-} (from TPC candidates) vs pair pt with one e in phos acceptance range", HistType::kTH2F, {axisMassSpectrum, axisPt}); + mHistManager.add("h_TPCee_MS_pp_phosRange_kTVXinPHOS", "Mass e^{+}e^{+} vs momentum e^{+}e^{+} (from TPC candidates) vs pair pt with one e in phos acceptance range", HistType::kTH2F, {axisMassSpectrum, axisPt}); mHistManager.add("hTrackVX", "Track vertex coordinate X", HistType::kTH1F, {axisVTrackX}); mHistManager.add("hTrackVY", "Track vertex coordinate Y", HistType::kTH1F, {axisVTrackY}); @@ -858,12 +918,23 @@ struct tpcElIdMassSpectrum { mHistManager.add("hTrackPt_Cut", "Track pt after cut", HistType::kTH1F, {axisPtBig}); mHistManager.add("hTrackEta", "Track eta", HistType::kTH1F, {axisEta}); mHistManager.add("hTrackEta_Cut", "Track eta after cut", HistType::kTH1F, {axisEta}); - - geomPHOS = std::make_unique("PHOS"); } void process(soa::Join::iterator const& collision, - soa::Filtered& tracks) + soa::Filtered const& tracks, + aod::BCsWithTimestamps const&) { + auto bc = collision.bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", bc.timestamp()); + if (grpo == nullptr) { + LOGF(fatal, "Run 3 GRP object (type o2::parameters::GRPMagField) is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + o2::base::Propagator::initFieldFromGRP(grpo); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + runNumber = bc.runNumber(); + } mHistManager.fill(HIST("eventCounter"), 0.5); if (fabs(collision.posZ()) > 10.f) return; @@ -898,23 +969,36 @@ struct tpcElIdMassSpectrum { P1.SetPxPyPzE(track1.px(), track1.py(), track1.pz(), track1.energy(0)); P2.SetPxPyPzE(track2.px(), track2.py(), track2.pz(), track2.energy(0)); - bool inPhosEtaRange = (fabs(track1.eta()) < 0.12 || fabs(track2.eta()) < 0.12); - bool inPhosPhiRange = (track1.phi() * TMath::RadToDeg() > 240 && track1.phi() * TMath::RadToDeg() < 310) || (track2.phi() * TMath::RadToDeg() > 240 && track2.phi() * TMath::RadToDeg() < 310); - bool inPhosRange = inPhosEtaRange && inPhosPhiRange; + bool inPhosEtaRange1 = fabs(track1.eta()) < 0.12; + bool inPhosEtaRange2 = fabs(track2.eta()) < 0.12; + bool inPhosPhiRange1 = (track1.phi() * TMath::RadToDeg() > 250 && track1.phi() * TMath::RadToDeg() < 320); + bool inPhosPhiRange2 = (track2.phi() * TMath::RadToDeg() > 250 && track2.phi() * TMath::RadToDeg() < 320); + bool inPhosRange = (inPhosEtaRange1 && inPhosPhiRange1) || (inPhosEtaRange2 && inPhosPhiRange2); + bool posTrack = (track1.sign() > 0 && bz > 0) || (track1.sign() < 0 && bz < 0); + if (track1.sign() == track2.sign()) { - if (track1.sign() > 0) { + if (posTrack) { mHistManager.fill(HIST("h_TPCee_MS_pp"), (P1 + P2).M(), (P1 + P2).Pt()); - if (inPhosRange) + if (inPhosRange) { mHistManager.fill(HIST("h_TPCee_MS_pp_phosRange"), (P1 + P2).M(), (P1 + P2).Pt()); + if (collision.alias_bit(kTVXinPHOS)) + mHistManager.fill(HIST("h_TPCee_MS_pp_phosRange_kTVXinPHOS"), (P1 + P2).M(), (P1 + P2).Pt()); + } } else { mHistManager.fill(HIST("h_TPCee_MS_mm"), (P1 + P2).M(), (P1 + P2).Pt()); - if (inPhosRange) + if (inPhosRange) { mHistManager.fill(HIST("h_TPCee_MS_mm_phosRange"), (P1 + P2).M(), (P1 + P2).Pt()); + if (collision.alias_bit(kTVXinPHOS)) + mHistManager.fill(HIST("h_TPCee_MS_mm_phosRange_kTVXinPHOS"), (P1 + P2).M(), (P1 + P2).Pt()); + } } } else { mHistManager.fill(HIST("h_TPCee_MS_mp"), (P1 + P2).M(), (P1 + P2).Pt()); - if (inPhosRange) + if (inPhosRange) { mHistManager.fill(HIST("h_TPCee_MS_mp_phosRange"), (P1 + P2).M(), (P1 + P2).Pt()); + if (collision.alias_bit(kTVXinPHOS)) + mHistManager.fill(HIST("h_TPCee_MS_mp_phosRange_kTVXinPHOS"), (P1 + P2).M(), (P1 + P2).Pt()); + } } } diff --git a/PWGHF/D2H/Core/SelectorCutsRedDataFormat.h b/PWGHF/D2H/Core/SelectorCutsRedDataFormat.h new file mode 100644 index 00000000000..a698b8152a6 --- /dev/null +++ b/PWGHF/D2H/Core/SelectorCutsRedDataFormat.h @@ -0,0 +1,81 @@ +// 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 SelectorCutsRedDataFormat.h +/// \brief Default pT bins and cut arrays for heavy-flavour selectors and analysis tasks +/// +/// \author Luca Aglietta , Università degli Studi di Torino + +// namespace with D selections for reduced charmed-resonances analysis + +#ifndef PWGHF_D2H_CORE_SELECTORCUTSREDDATAFORMAT_H_ +#define PWGHF_D2H_CORE_SELECTORCUTSREDDATAFORMAT_H_ + +#include // std::string +#include // std::vector + +namespace hf_cuts_d_daughter +{ +const int nBinsPt = 7; +static constexpr int nCutVars = 6; +constexpr double binsPt[nBinsPt + 1] = { + 1., + 2., + 4., + 6., + 8., + 12., + 24., + 1000.}; +auto vecBinsPt = std::vector{binsPt, binsPt + nBinsPt + 1}; +// default values for the cuts +constexpr double cuts[nBinsPt][nCutVars] = {{1.84, 1.89, 1.77, 1.81, 1.92, 1.96}, /* 1 < pt < 2 */ + {1.84, 1.89, 1.77, 1.81, 1.92, 1.96}, /* 2 < pt < 4 */ + {1.84, 1.89, 1.77, 1.81, 1.92, 1.96}, /* 4 < pt < 6 */ + {1.84, 1.89, 1.77, 1.81, 1.92, 1.96}, /* 6 < pt < 8 */ + {1.84, 1.89, 1.77, 1.81, 1.92, 1.96}, /* 8 < pt < 12 */ + {1.84, 1.89, 1.77, 1.81, 1.92, 1.96}, /* 12 < pt < 24 */ + {1.84, 1.89, 1.77, 1.81, 1.92, 1.96}}; /* 24 < pt < 1000 */ +// row labels +static const std::vector labelsPt{}; +// column labels +static const std::vector labelsCutVar = {"invMassSignalLow", "invMassSignalHigh", "invMassLeftSBLow", "invMassLeftSBHigh", "invMassRightSBLow", "invMassRightSBHigh"}; +} // namespace hf_cuts_d_daughter + +// namespace with v0 selections for reduced charmed-resonances analysis +namespace hf_cuts_v0_daughter +{ +const int nBinsPt = 7; +static constexpr int nCutVars = 5; +constexpr double binsPt[nBinsPt + 1] = { + 0., + 1., + 2., + 4., + 8., + 12., + 24., + 1000.}; +auto vecBinsPt = std::vector{binsPt, binsPt + nBinsPt + 1}; +// default values for the cuts +constexpr double cuts[nBinsPt][nCutVars] = {{0.48, 0.52, 0.99, 1., 0.9}, /* 1 < pt < 2 */ + {0.48, 0.52, 0.99, 1., 0.9}, /* 2 < pt < 4 */ + {0.48, 0.52, 0.99, 1., 0.9}, /* 4 < pt < 6 */ + {0.48, 0.52, 0.99, 1., 0.9}, /* 6 < pt < 8 */ + {0.48, 0.52, 0.99, 1., 0.9}, /* 8 < pt < 12 */ + {0.48, 0.52, 0.99, 1., 0.9}, /* 12 < pt < 24 */ + {0.48, 0.52, 0.99, 1., 0.9}}; /* 24 < pt < 1000 */ +// row labels +static const std::vector labelsPt{}; +// column labels +static const std::vector labelsCutVar = {"invMassLow", "invMassHigh", "cpaMin", "dcaMax", "radiusMin"}; +} // namespace hf_cuts_v0_daughter +#endif // PWGHF_D2H_CORE_SELECTORCUTSREDDATAFORMAT_H_ diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index d63b5f15957..07fe57f18bc 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -427,15 +427,25 @@ DECLARE_SOA_TABLE(HfCandBpConfigs, "AOD", "HFCANDBPCONFIG", //! Table with confi // Charm resonances analysis namespace hf_reso_cand_reduced { -DECLARE_SOA_COLUMN(InvMass, invMass, float); //! Invariant mass in GeV/c2 -DECLARE_SOA_COLUMN(Pt, pt, float); //! Pt of Resonance candidate in GeV/c -DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Pt of D daughter in GeV/c -DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Pt of V0 daughter in GeV/c +DECLARE_SOA_COLUMN(InvMass, invMass, float); //! Invariant mass in GeV/c2 DECLARE_SOA_COLUMN(InvMassProng0, invMassProng0, float); //! Invariant Mass of D daughter in GeV/c DECLARE_SOA_COLUMN(InvMassProng1, invMassProng1, float); //! Invariant Mass of V0 daughter in GeV/c DECLARE_SOA_COLUMN(MlScoreBkgProng0, mlScoreBkgProng0, float); //! Bkg ML score of the D daughter DECLARE_SOA_COLUMN(MlScorePromptProng0, mlScorePromptProng0, float); //! Prompt ML score of the D daughter DECLARE_SOA_COLUMN(MlScoreNonpromptProng0, mlScoreNonpromptProng0, float); //! Nonprompt ML score of the D daughter + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! + [](float pxProng0, float pxProng1, float pyProng0, float pyProng1) -> float { return RecoDecay::pt((1.f * pxProng0 + 1.f * pxProng1), (1.f * pyProng0 + 1.f * pyProng1)); }); +DECLARE_SOA_DYNAMIC_COLUMN(PtProng0, ptProng0, //! + [](float pxProng0, float pyProng0) -> float { return RecoDecay::pt(pxProng0, pyProng0); }); +DECLARE_SOA_DYNAMIC_COLUMN(PtProng1, ptProng1, //! + [](float pxProng1, float pyProng1) -> float { return RecoDecay::pt(pxProng1, pyProng1); }); +DECLARE_SOA_DYNAMIC_COLUMN(CosThetaStarDs1, cosThetaStarDs1, //! costhetastar under Ds1 hypothesis + [](float px0, float py0, float pz0, float px1, float py1, float pz1, float invMass) -> float { return RecoDecay::cosThetaStar(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{o2::constants::physics::MassDStar, o2::constants::physics::MassK0}, invMass, 1); }); +DECLARE_SOA_DYNAMIC_COLUMN(CosThetaStarDs2Star, cosThetaStarDs2Star, //! costhetastar under Ds2Star hypothesis + [](float px0, float py0, float pz0, float px1, float py1, float pz1, float invMass) -> float { return RecoDecay::cosThetaStar(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassK0}, invMass, 1); }); +DECLARE_SOA_DYNAMIC_COLUMN(CosThetaStarXiC3055, cosThetaStarXiC3055, //! costhetastar under XiC3055 hypothesis + [](float px0, float py0, float pz0, float px1, float py1, float pz1, float invMass) -> float { return RecoDecay::cosThetaStar(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassLambda0}, invMass, 1); }); } // namespace hf_reso_cand_reduced namespace hf_reso_3_prong @@ -474,7 +484,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! [](float pzProng0, float pzProng1) -> float { return 1.f * pzProng0 + 1.f * pzProng1; }); DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! [](float pxProng0, float pxProng1, float pyProng0, float pyProng1) -> float { return RecoDecay::pt((1.f * pxProng0 + 1.f * pxProng1), (1.f * pyProng0 + 1.f * pyProng1)); }); -DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, //! V0 decay radius (2D, centered at zero) +DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0Radius, //! V0 decay radius (2D, centered at zero) [](float x, float y) -> float { return RecoDecay::sqrtSumOfSquares(x, y); }); DECLARE_SOA_DYNAMIC_COLUMN(InvMassLambda, invMassLambda, //! mass under lambda hypothesis [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); }); @@ -571,16 +581,26 @@ DECLARE_SOA_TABLE(HfRed3PrNoTrks, "AOD", "HFRED3PRNOTRK", //! Table with 3 prong DECLARE_SOA_TABLE(HfCandCharmReso, "AOD", "HFCANDCHARMRESO", //! Table with Resonance candidate information for resonances reduced workflow o2::soa::Index<>, + // Indices hf_track_index_reduced::HfRedCollisionId, + // Static + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, hf_reso_cand_reduced::InvMass, - hf_reso_cand_reduced::Pt, hf_reso_cand_reduced::InvMassProng0, - hf_reso_cand_reduced::PtProng0, hf_reso_cand_reduced::InvMassProng1, - hf_reso_cand_reduced::PtProng1, hf_reso_v0::Cpa, hf_reso_v0::Dca, - hf_reso_v0::Radius); + hf_reso_v0::Radius, + // Dynamic + hf_reso_cand_reduced::Pt, + hf_reso_cand_reduced::PtProng0, + hf_reso_cand_reduced::PtProng1, + hf_cand::PVectorProng0, + hf_cand::PVectorProng1, + hf_reso_cand_reduced::CosThetaStarDs1, + hf_reso_cand_reduced::CosThetaStarDs2Star, + hf_reso_cand_reduced::CosThetaStarXiC3055); DECLARE_SOA_TABLE(HfCharmResoMLs, "AOD", "HFCHARMRESOML", //! Table with ML scores for the D daughter hf_reso_cand_reduced::MlScoreBkgProng0, diff --git a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx index 79b6c92311e..c3f3af5086b 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx @@ -22,11 +22,15 @@ #include "Common/Core/trackUtilities.h" #include "Common/DataModel/CollisionAssociationTables.h" +#include "EventFiltering/PWGHF/HFFilterHelpers.h" #include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/D2H/Core/SelectorCutsRedDataFormat.h" +#include "PWGHF/Utils/utilsAnalysis.h" using namespace o2; using namespace o2::aod; +using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; @@ -47,8 +51,9 @@ enum V0Type : uint8_t { Lambda, AntiLambda }; -const int nBins = 7; -constexpr double binsPt[nBins + 1] = { + +const int nBinsPt = 7; +constexpr double binsPt[nBinsPt + 1] = { 1., 2., 4., @@ -56,23 +61,26 @@ constexpr double binsPt[nBins + 1] = { 8., 12., 24., - 50.}; -auto vecBins = std::vector{binsPt, binsPt + nBins + 1}; + 1000.}; +auto vecBinsPt = std::vector{binsPt, binsPt + nBinsPt + 1}; struct HfCandidateCreatorCharmResoReduced { // Produces: Tables with resonance info Produces rowCandidateReso; - // Optional D daughter ML scores table + // Optional daughter ML scores table Produces mlScores; // Configurables - Configurable invMassWindowD{"invMassWindowD", 0.5, "invariant-mass window for D candidates (GeV/c2)"}; - Configurable invMassWindowV0{"invMassWindowV0", 0.5, "invariant-mass window for V0 candidates (GeV/c2)"}; Configurable rejectDV0PairsWithCommonDaughter{"rejectDV0PairsWithCommonDaughter", true, "flag to reject the pairs that share a daughter track if not done in the derived data creation"}; + Configurable keepSideBands{"keepSideBands", false, "flag to keep events from D meson sidebands for backgorund estimation"}; // QA switch Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; - // Hist Axis - Configurable> binsPt{"binsPt", std::vector{vecBins}, "pT bin limits"}; + Configurable> binsPt{"binsPt", std::vector{vecBinsPt}, "Histogram pT bin limits"}; + // Daughters selection cuts + Configurable> cutsD{"cutsDdaughter", {hf_cuts_d_daughter::cuts[0], hf_cuts_d_daughter::nBinsPt, hf_cuts_d_daughter::nCutVars, hf_cuts_d_daughter::labelsPt, hf_cuts_d_daughter::labelsCutVar}, "D daughter selections"}; + Configurable> binsPtD{"binsPtD", std::vector{hf_cuts_d_daughter::vecBinsPt}, "pT bin limits for D daughter cuts"}; + Configurable> cutsV0{"cutsV0daughter", {hf_cuts_v0_daughter::cuts[0], hf_cuts_v0_daughter::nBinsPt, hf_cuts_v0_daughter::nCutVars, hf_cuts_v0_daughter::labelsPt, hf_cuts_v0_daughter::labelsCutVar}, "V0 daughter selections"}; + Configurable> binsPtV0{"binsPtV0", std::vector{hf_cuts_v0_daughter::vecBinsPt}, "pT bin limits for V0 daughter cuts"}; using reducedDWithMl = soa::Join; @@ -82,7 +90,7 @@ struct HfCandidateCreatorCharmResoReduced { Preslice candsV0PerCollision = aod::hf_track_index_reduced::hfRedCollisionId; Preslice candsDPerCollision = hf_track_index_reduced::hfRedCollisionId; - // aod::HfRedVzeros + // Useful constants double massK0{0.}; double massLambda{0.}; @@ -90,7 +98,6 @@ struct HfCandidateCreatorCharmResoReduced { double massDstar{0.}; double massD0{0.}; - // Histogram registry: if task make it with a THNsparse with all variables you want to save HistogramRegistry registry{"registry"}; void init(InitContext const&) @@ -101,7 +108,7 @@ struct HfCandidateCreatorCharmResoReduced { LOGP(fatal, "Only one process function should be enabled! Please check your configuration!"); } // histograms - const AxisSpec axisPt{(std::vector)vecBins, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisPt{(std::vector)vecBinsPt, "#it{p}_{T} (GeV/#it{c})"}; registry.add("hMassDs1", "Ds1 candidates;m_{Ds1} (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{100, 2.4, 2.7}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hMassDs2Star", "Ds^{*}2 candidates; m_Ds^{*}2 (GeV/#it{c}^{2}) ;entries", {HistType::kTH2F, {{100, 2.4, 2.7}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hMassXcRes", "XcRes candidates; m_XcRes (GeV/#it{c}^{2}) ;entries", {HistType::kTH2F, {{100, 2.9, 3.3}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -131,21 +138,33 @@ struct HfCandidateCreatorCharmResoReduced { template bool isDSelected(DRedTable const& candD) { - float massD{0.}; float invMassD{0.}; + float ptD = candD.pt(); + int ptBin = findBin(binsPtD, ptD); + if (ptBin == -1) { + return false; + } // slection on D candidate mass if (channel == DecayChannel::Ds2StarToDplusK0s || channel == DecayChannel::XcToDplusLambda || channel == DecayChannel::LambdaDminus) { - massD = massDplus; invMassD = candD.invMassDplus(); } else if (channel == DecayChannel::Ds1ToDstarK0s) { - massD = massDstar - massD0; if (candD.dType() > 0) invMassD = candD.invMassDstar(); else invMassD = candD.invMassAntiDstar(); } - if (std::fabs(invMassD - massD) > invMassWindowD) { - return false; + // invariant mass selection + if (!keepSideBands) { + if (invMassD < cutsD->get(ptBin, "invMassSignalLow") || invMassD > cutsD->get(ptBin, "invMassSignalHigh")) { + return false; + } + } else { + if ((invMassD < cutsD->get(ptBin, "invMassLeftSBLow")) || + (invMassD > cutsD->get(ptBin, "invMassLeftSBHigh") && invMassD < cutsD->get(ptBin, "invMassSignalLow")) || + (invMassD > cutsD->get(ptBin, "invMassSignalHigh") && invMassD < cutsD->get(ptBin, "invMassRightSBLow")) || + (invMassD > cutsD->get(ptBin, "invMassRightSBHigh"))) { + return false; + } } return true; } @@ -159,6 +178,11 @@ struct HfCandidateCreatorCharmResoReduced { { float massV0{0.}; float invMassV0{0.}; + float ptV0 = candV0.pt(); + int ptBin = findBin(binsPtV0, ptV0); + if (ptBin == -1) { + return false; + } if (channel == DecayChannel::Ds2StarToDplusK0s || channel == DecayChannel::Ds1ToDstarK0s) { massV0 = massK0; invMassV0 = candV0.invMassK0s(); @@ -175,12 +199,17 @@ struct HfCandidateCreatorCharmResoReduced { invMassV0 = candV0.invMassAntiLambda(); targetV0Type = V0Type::AntiLambda; } + // check skimming cuts if (!TESTBIT(candV0.v0Type(), targetV0Type)) { return false; } } - // slection on V0 candidate mass - if (std::fabs(invMassV0 - massV0) > invMassWindowV0) { + // selection on V0 candidate mass + if ((invMassV0 - massV0) > cutsV0->get(ptBin, "invMassLow") && (massV0 - invMassV0) < cutsV0->get(ptBin, "invMassLow")) { + return false; + } + // selection on kinematics and topology + if (candV0.dca() > cutsV0->get(ptBin, "dcaMax") || candV0.cpa() < cutsV0->get(ptBin, "cpaMin") || candV0.v0Radius() < cutsV0->get(ptBin, "radiusMin")) { return false; } return true; @@ -211,7 +240,7 @@ struct HfCandidateCreatorCharmResoReduced { if (candD.dType() == -2) invMassD = candD.invMassAntiDstar(); std::array pVecD = {candD.px(), candD.py(), candD.pz()}; - float ptD = RecoDecay::pt(pVecD); + std::array dDaughtersIds = {candD.prong0Id(), candD.prong1Id(), candD.prong2Id()}; ; // loop on V0 candidates bool alreadyCounted{false}; @@ -233,7 +262,6 @@ struct HfCandidateCreatorCharmResoReduced { float invMassReso{0.}; float invMassV0{0.}; std::array pVecV0 = {candV0.px(), candV0.py(), candV0.pz()}; - float ptV0 = RecoDecay::pt(pVecV0); float ptReso = RecoDecay::pt(RecoDecay::sumOfVec(pVecV0, pVecD)); switch (channel) { case DecayChannel::Ds1ToDstarK0s: @@ -269,15 +297,14 @@ struct HfCandidateCreatorCharmResoReduced { } // Filling Output table rowCandidateReso(collision.globalIndex(), + pVecD[0], pVecD[1], pVecD[2], + pVecV0[0], pVecV0[1], pVecV0[2], invMassReso, - ptReso, invMassD, - ptD, invMassV0, - ptV0, candV0.cpa(), candV0.dca(), - candV0.v0radius()); + candV0.v0Radius()); if constexpr (fillMl) { mlScores(candD.mlScoreBkgMassHypo0(), candD.mlScorePromptMassHypo0(), candD.mlScoreNonpromptMassHypo0()); } diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index 60e5a47fc3f..70837975a00 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(task-charm-polarisation PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-charm-reso-reduced + SOURCES taskCharmResoReduced.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-d0 SOURCES taskD0.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx b/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx new file mode 100644 index 00000000000..d50644fe55e --- /dev/null +++ b/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx @@ -0,0 +1,238 @@ +// 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 taskCharmResoReduced.cxx +/// \brief Charmed Resonances analysis task +/// +/// \author Luca Aglietta , University and INFN Torino + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/RecoDecay.h" + +// #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::analysis; +using namespace o2::framework; +using namespace o2::framework::expressions; + +enum DecayChannel : uint8_t { + Ds1ToDstarK0s = 0, + Ds2StarToDplusK0s, + XcToDplusLambda, + LambdaDminus +}; + +struct HfTaskCharmResoReduced { + Configurable ptMinReso{"ptMinReso", 5, "Discard events with smaller pT"}; + Configurable cutBeforeMixing{"cutBeforeMixing", false, "Apply pT cut to candidates before event mixing"}; + Configurable cutAfterMixing{"cutAfterMixing", false, "Apply pT cut to candidates after event mixing"}; + // Configurables axis for histos + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0., 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 8.f, 12.f, 24.f, 50.f}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis axisPtProng0{"axisPtProng0", {VARIABLE_WIDTH, 0., 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 8.f, 12.f, 24.f, 50.f}, "prong0 bach. #it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis axisPtProng1{"axisPtProng1", {VARIABLE_WIDTH, 0., 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 8.f, 12.f, 24.f, 50.f}, "prong1 bach. #it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis axisInvMassReso{"axisInvMassReso", {200, 2.34, 2.74}, "inv. mass (DV_{0}) (GeV/#it{c}^{2})"}; + ConfigurableAxis axisInvMassProng0{"axisInvMassProng0", {175, 1.70, 2.05}, "inv. mass (D) (GeV/#it{c}^{2})"}; + ConfigurableAxis axisInvMassProng1{"axisInvMassProng1", {80, 0.46, 0.54}, "inv. mass ({V}_{0}) (GeV/#it{c}^{2})"}; + ConfigurableAxis axisCosThetaStar{"axisCosThetaStar", {40, -1, 1}, "cos(#vartheta*)"}; + ConfigurableAxis axisBkgBdtScore{"axisBkgBdtScore", {100, 0, 1}, "bkg BDT Score"}; + ConfigurableAxis axisNonPromptBdtScore{"axisNonPromptBdtScore", {100, 0, 1}, "non-prompt BDT Score"}; + // Configurables for ME + Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; + Configurable numberEventsToSkip{"numberEventsToSkip", -1, "Number of events to Skip in ME process"}; + 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"}; + // ConfigurableAxis bzPoolBins{"bzPoolBins", {2, -10, 10}, "Bz of collision"}; + + using ReducedResoWithMl = soa::Join; + SliceCache cache; + Preslice resoPerCollision = aod::hf_track_index_reduced::hfRedCollisionId; + + // Histogram Registry + HistogramRegistry registry; + + // init + void init(InitContext&) + { + registry.add("hMass", "Charm resonance candidates inv. mass", {HistType::kTH1F, {axisInvMassReso}}); + registry.add("hMassProng0", "D daughters inv. mass", {HistType::kTH1F, {axisInvMassProng0}}); + registry.add("hMassProng1", "V0 daughter inv. mass", {HistType::kTH1F, {axisInvMassProng1}}); + registry.add("hPt", "Charm resonance candidates pT", {HistType::kTH1F, {axisPt}}); + registry.add("hPtProng0", "D daughters pT", {HistType::kTH1F, {axisPtProng0}}); + registry.add("hPtProng1", "V0 daughter pT", {HistType::kTH1F, {axisPtProng1}}); + registry.add("hNPvCont", "Collision number of PV contributors ; N contrib ; entries", {HistType::kTH1F, {{100, 0, 250}}}); + registry.add("hZvert", "Collision Z Vtx ; z PV [cm] ; entries", {HistType::kTH1F, {{120, -12., 12.}}}); + registry.add("hBz", "Collision Bz ; Bz [T] ; entries", {HistType::kTH1F, {{20, -10., 10.}}}); + registry.add("hSparse", "THn for production studies with cosThStar and BDT scores", HistType::kTHnSparseF, {axisPt, axisPtProng0, axisPtProng1, axisInvMassReso, axisInvMassProng0, axisInvMassProng1, axisCosThetaStar, axisBkgBdtScore, axisNonPromptBdtScore}); + + if (doprocessDs1DataMixedEvent || doprocessDs2StarDataMixedEvent) { + registry.add("hNPvContCorr", "Collision number of PV contributors ; N contrib ; N contrib", {HistType::kTH2F, {{100, 0, 250}, {100, 0, 250}}}); + registry.add("hZvertCorr", "Collision Z Vtx ; z PV [cm] ; z PV [cm]", {HistType::kTH2F, {{120, -12., 12.}, {120, -12., 12.}}}); + registry.add("hMassProng0Corr", "D daughters inv. mass", {HistType::kTH2F, {axisInvMassProng0, axisInvMassProng0}}); + registry.add("hMassProng1Corr", "V0 daughter inv. mass", {HistType::kTH2F, {axisInvMassProng1, axisInvMassProng1}}); + } + } + + // Fill histograms + /// \tparam channel is the decay channel of the Resonance + /// \param candidate is a candidate + /// \param coll is a reduced collision + template + void fillHisto(const Cand& candidate, const Coll& collision) + { + // Collision properties + registry.fill(HIST("hNPvCont"), collision.numContrib()); + registry.fill(HIST("hZvert"), collision.posZ()); + registry.fill(HIST("hBz"), collision.bz()); + // Candidate properties + registry.fill(HIST("hMass"), candidate.invMass()); + registry.fill(HIST("hMassProng0"), candidate.invMassProng0()); + registry.fill(HIST("hMassProng1"), candidate.invMassProng1()); + registry.fill(HIST("hPt"), candidate.pt()); + registry.fill(HIST("hPtProng0"), candidate.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate.ptProng1()); + float cosThetaStar{0.}; + switch (channel) { + case DecayChannel::Ds1ToDstarK0s: + cosThetaStar = candidate.cosThetaStarDs1(); + break; + case DecayChannel::Ds2StarToDplusK0s: + cosThetaStar = candidate.cosThetaStarDs2Star(); + break; + default: + cosThetaStar = candidate.cosThetaStarXiC3055(); + break; + } + registry.fill(HIST("hSparse"), candidate.pt(), candidate.ptProng0(), candidate.ptProng1(), candidate.invMass(), candidate.invMassProng0(), candidate.invMassProng1(), cosThetaStar, candidate.mlScoreBkgProng0(), candidate.mlScoreNonpromptProng0()); + } // fillHisto + + // Process data + /// \tparam channel is the decay channel of the Resonance + /// \param Coll is the reduced collisions table + /// \param Cand is the candidates table + template + void processData(Coll const&, Candidates const& candidates) + { + for (const auto& cand : candidates) { + if (cand.pt() < ptMinReso) { + continue; + } + auto coll = cand.template hfRedCollision_as(); + fillHisto(cand, coll); + } + } + + // Process data with Mixed Event + /// \tparam channel is the decay channel of the Resonance + /// \param Coll is the reduced collisions table + /// \param Cand is the candidates table + template + void processDataMixedEvent(Coll const& collisions, Candidates const& candidates) + { + using BinningType = ColumnBinningPolicy; + BinningType corrBinning{{zPoolBins, multPoolBins}, true}; + auto candsTuple = std::make_tuple(candidates); + SameKindPair pairs{corrBinning, numberEventsMixed, numberEventsToSkip, collisions, candsTuple, &cache}; + for (const auto& [collision1, cands1, collision2, cands2] : pairs) { + // For each couple of candidate resonances I can make 2 mixed candidates by swithching daughters + for (const auto& [cand1, cand2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(cands1, cands2))) { + if (cutBeforeMixing && (cand1.pt() < ptMinReso || cand2.pt() < ptMinReso)) { + continue; + } + float ptME1 = RecoDecay::pt(cand1.pVectorProng0(), cand2.pVectorProng1()); + float invMassME1; + float cosThetaStarME1; + if (!cutAfterMixing || ptME1 > ptMinReso) { + switch (channel) { + case DecayChannel::Ds1ToDstarK0s: + invMassME1 = RecoDecay::m(std::array{cand1.pVectorProng0(), cand2.pVectorProng1()}, std::array{o2::constants::physics::MassDStar, o2::constants::physics::MassK0Short}); + cosThetaStarME1 = RecoDecay::cosThetaStar(std::array{cand1.pVectorProng0(), cand2.pVectorProng1()}, std::array{o2::constants::physics::MassDStar, o2::constants::physics::MassK0Short}, invMassME1, 1); + break; + case DecayChannel::Ds2StarToDplusK0s: + invMassME1 = RecoDecay::m(std::array{cand1.pVectorProng0(), cand2.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassK0Short}); + cosThetaStarME1 = RecoDecay::cosThetaStar(std::array{cand1.pVectorProng0(), cand2.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassK0Short}, invMassME1, 1); + break; + default: + invMassME1 = RecoDecay::m(std::array{cand1.pVectorProng0(), cand2.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassLambda0}); + cosThetaStarME1 = RecoDecay::cosThetaStar(std::array{cand1.pVectorProng0(), cand2.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassLambda0}, invMassME1, 1); + break; + } + registry.fill(HIST("hMass"), invMassME1); + registry.fill(HIST("hPt"), ptME1); + registry.fill(HIST("hNPvContCorr"), collision1.numContrib(), collision2.numContrib()); + registry.fill(HIST("hZvertCorr"), collision1.posZ(), collision2.posZ()); + registry.fill(HIST("hMassProng0Corr"), cand1.invMassProng0(), cand2.invMassProng0()); + registry.fill(HIST("hMassProng1Corr"), cand1.invMassProng1(), cand2.invMassProng1()); + registry.fill(HIST("hSparse"), ptME1, cand1.ptProng0(), cand2.ptProng1(), invMassME1, cand1.invMassProng0(), cand2.invMassProng1(), cosThetaStarME1, cand1.mlScoreBkgProng0(), cand1.mlScoreNonpromptProng0()); + } + float ptME2 = RecoDecay::pt(cand2.pVectorProng0(), cand1.pVectorProng1()); + float invMassME2; + float cosThetaStarME2; + if (!cutAfterMixing || ptME2 > ptMinReso) { + switch (channel) { + case DecayChannel::Ds1ToDstarK0s: + invMassME2 = RecoDecay::m(std::array{cand2.pVectorProng0(), cand1.pVectorProng1()}, std::array{o2::constants::physics::MassDStar, o2::constants::physics::MassK0Short}); + cosThetaStarME2 = RecoDecay::cosThetaStar(std::array{cand2.pVectorProng0(), cand1.pVectorProng1()}, std::array{o2::constants::physics::MassDStar, o2::constants::physics::MassK0Short}, invMassME2, 1); + break; + case DecayChannel::Ds2StarToDplusK0s: + invMassME2 = RecoDecay::m(std::array{cand2.pVectorProng0(), cand1.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassK0Short}); + cosThetaStarME2 = RecoDecay::cosThetaStar(std::array{cand2.pVectorProng0(), cand1.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassK0Short}, invMassME2, 1); + break; + default: + invMassME2 = RecoDecay::m(std::array{cand2.pVectorProng0(), cand1.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassLambda0}); + cosThetaStarME2 = RecoDecay::cosThetaStar(std::array{cand2.pVectorProng0(), cand1.pVectorProng1()}, std::array{o2::constants::physics::MassDPlus, o2::constants::physics::MassLambda0}, invMassME2, 1); + break; + } + registry.fill(HIST("hMass"), invMassME2); + registry.fill(HIST("hPt"), ptME2); + registry.fill(HIST("hSparse"), ptME2, cand2.ptProng0(), cand1.ptProng1(), invMassME2, cand2.invMassProng0(), cand1.invMassProng1(), cosThetaStarME2, cand2.mlScoreBkgProng0(), cand2.mlScoreNonpromptProng0()); + } + } + } + } + + // process functions + + void processDs1Data(aod::HfRedCollisions const& collisions, ReducedResoWithMl const& candidates) + { + processData(collisions, candidates); + } + PROCESS_SWITCH(HfTaskCharmResoReduced, processDs1Data, "Process data", true); + + void processDs1DataMixedEvent(aod::HfRedCollisions const& collisions, ReducedResoWithMl const& candidates) + { + processDataMixedEvent(collisions, candidates); + } + PROCESS_SWITCH(HfTaskCharmResoReduced, processDs1DataMixedEvent, "Process data with Event Mixing", false); + + void processDs2StarData(aod::HfRedCollisions const& collisions, ReducedResoWithMl const& candidates) + { + processData(collisions, candidates); + } + PROCESS_SWITCH(HfTaskCharmResoReduced, processDs2StarData, "Process data", false); + + void processDs2StarDataMixedEvent(aod::HfRedCollisions const& collisions, ReducedResoWithMl const& candidates) + { + processDataMixedEvent(collisions, candidates); + } + PROCESS_SWITCH(HfTaskCharmResoReduced, processDs2StarDataMixedEvent, "Process data with Event Mixing", false); + +}; // struct HfTaskCharmResoReduced +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index a613d58eaaa..e486e7bb33b 100644 --- a/PWGHF/HFC/DataModel/CorrelationTables.h +++ b/PWGHF/HFC/DataModel/CorrelationTables.h @@ -347,6 +347,22 @@ DECLARE_SOA_COLUMN(DmesonSel, dmesonSel, bool); //! Selection flag for D meson i DECLARE_SOA_TABLE(DmesonSelection, "AOD", "DINCOLL", // Selection of D meson in collisions aod::hf_selection_dmeson_collision::DmesonSel); + +// Note: definition of columns and tables for Electron Hadron correlation pairs +namespace hf_correlation_electron_hadron +{ +DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, float); //! DeltaPhi between Electron and Hadrons +DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); //! DeltaEta between Electron and Hadrons +DECLARE_SOA_COLUMN(PtElectron, ptElectron, float); //! Transverse momentum of Electron +DECLARE_SOA_COLUMN(PtHadron, ptHadron, float); //! Transverse momentum of Hadron; +DECLARE_SOA_COLUMN(PoolBin, poolBin, int); //! Pool Bin of event defined using zvtx and multiplicity +} // namespace hf_correlation_electron_hadron +DECLARE_SOA_TABLE(HfEHadronPair, "AOD", "HFEHADRONPAIR", //! Hfe-Hadrons pairs Informations + hf_correlation_electron_hadron::DeltaPhi, + hf_correlation_electron_hadron::DeltaEta, + hf_correlation_electron_hadron::PtElectron, + hf_correlation_electron_hadron::PtHadron, + hf_correlation_electron_hadron::PoolBin); } // namespace o2::aod #endif // PWGHF_HFC_DATAMODEL_CORRELATIONTABLES_H_ diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 1a888dfc1d7..2b01aad32c6 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -49,6 +49,11 @@ o2physics_add_dpl_workflow(correlator-dstar-hadrons PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(correlator-hfe-hadrons + SOURCES correlatorHfeHadrons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(correlator-lc-hadrons SOURCES correlatorLcHadrons.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx index aef44ea068d..166ebb7eab8 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx @@ -162,7 +162,8 @@ struct HfCorrelatorDplusHadrons { Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for Dplus"}; // 7 corresponds to topo+PID cuts Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; - Configurable applyEfficiency{"applyEfficiency", 1, "Flag for applying D-meson efficiency weights"}; + Configurable applyEfficiency{"applyEfficiency", true, "Flag for applying D-meson efficiency weights"}; + Configurable removeDaughters{"removeDaughters", true, "Flag for removing D-meson daughters from correlations"}; Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen. cand. rapidity"}; Configurable etaTrackMax{"etaTrackMax", 0.8, "max. eta of tracks"}; @@ -352,8 +353,10 @@ struct HfCorrelatorDplusHadrons { continue; } // Removing Dplus daughters by checking track indices - if ((candidate.prong0Id() == track.globalIndex()) || (candidate.prong1Id() == track.globalIndex()) || (candidate.prong2Id() == track.globalIndex())) { - continue; + if (removeDaughters) { + if ((candidate.prong0Id() == track.globalIndex()) || (candidate.prong1Id() == track.globalIndex()) || (candidate.prong2Id() == track.globalIndex())) { + continue; + } } entryDplusHadronPair(getDeltaPhi(track.phi(), candidate.phi()), track.eta() - candidate.eta(), @@ -404,7 +407,7 @@ struct HfCorrelatorDplusHadrons { // MC reco level bool isDplusPrompt = false; bool isDplusNonPrompt = false; - bool flagDplusSignal = false; + bool isDplusSignal = false; for (const auto& candidate : candidates) { // rapidity and pT selections if (std::abs(hfHelper.yDplus(candidate)) >= yCandMax || candidate.pt() <= ptCandMin || candidate.pt() >= ptCandMax) { @@ -417,7 +420,7 @@ struct HfCorrelatorDplusHadrons { efficiencyWeightD = 1. / efficiencyD->at(effBinD); } // Dplus flag - flagDplusSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; + isDplusSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::DplusToPiKPi); // prompt and non-prompt division isDplusPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; isDplusNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; @@ -428,7 +431,7 @@ struct HfCorrelatorDplusHadrons { registry.fill(HIST("hMassDplusMcRec"), hfHelper.invMassDplusToPiKPi(candidate), efficiencyWeightD); registry.fill(HIST("hDplusBin"), poolBin); - if (flagDplusSignal) { + if (isDplusSignal) { // fill per-candidate distributions from Dplus true candidates registry.fill(HIST("hPtProng0MCRec"), candidate.ptProng0()); registry.fill(HIST("hPtProng1MCRec"), candidate.ptProng1()); @@ -472,14 +475,16 @@ struct HfCorrelatorDplusHadrons { continue; } // Removing Dplus daughters by checking track indices - if ((candidate.prong0Id() == track.globalIndex()) || (candidate.prong1Id() == track.globalIndex()) || (candidate.prong2Id() == track.globalIndex())) { - continue; + if (removeDaughters) { + if ((candidate.prong0Id() == track.globalIndex()) || (candidate.prong1Id() == track.globalIndex()) || (candidate.prong2Id() == track.globalIndex())) { + continue; + } } entryDplusHadronPair(getDeltaPhi(track.phi(), candidate.phi()), track.eta() - candidate.eta(), candidate.pt(), track.pt(), poolBin); - entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), flagDplusSignal); + entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), isDplusSignal); entryDplusHadronMlInfo(outputMl[0], outputMl[1]); if (track.has_mcParticle()) { auto mcParticle = track.template mcParticle_as(); @@ -517,12 +522,16 @@ struct HfCorrelatorDplusHadrons { registry.fill(HIST("hMultFT0AMcGen"), mcCollision.multMCFT0A()); bool isDplusPrompt = false; + bool isDplusNonPrompt = false; // MC gen level for (const auto& particle1 : mcParticles) { // check if the particle is Dplus (for general plot filling and selection, so both cases are fine) - NOTE: decay channel is not probed! if (std::abs(particle1.pdgCode()) != Pdg::kDPlus) { continue; } + if (!TESTBIT(std::abs(particle1.flagMcMatchGen()), aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { + continue; + } double yD = RecoDecay::y(particle1.pVector(), MassDPlus); if (std::abs(yD) >= yCandMax || particle1.pt() <= ptCandMin) { continue; @@ -535,9 +544,10 @@ struct HfCorrelatorDplusHadrons { // prompt and non-prompt division isDplusPrompt = particle1.originMcGen() == RecoDecay::OriginType::Prompt; + isDplusNonPrompt = particle1.originMcGen() == RecoDecay::OriginType::NonPrompt; if (isDplusPrompt) { registry.fill(HIST("hPtCandMcGenPrompt"), particle1.pt()); - } else { + } else if (isDplusNonPrompt) { registry.fill(HIST("hPtCandMcGenNonPrompt"), particle1.pt()); } @@ -563,8 +573,10 @@ struct HfCorrelatorDplusHadrons { if (std::abs(particleAssoc.eta()) > etaTrackMax || particleAssoc.pt() < ptTrackMin || particleAssoc.pt() > ptTrackMax) { continue; } - if (particleAssoc.globalIndex() == prongsId[0] || particleAssoc.globalIndex() == prongsId[1] || particleAssoc.globalIndex() == prongsId[2]) { - continue; + if (removeDaughters) { + if (particleAssoc.globalIndex() == prongsId[0] || particleAssoc.globalIndex() == prongsId[1] || particleAssoc.globalIndex() == prongsId[2]) { + continue; + } } if ((std::abs(particleAssoc.pdgCode()) != kElectron) && (std::abs(particleAssoc.pdgCode()) != kMuonMinus) && (std::abs(particleAssoc.pdgCode()) != kPiPlus) && (std::abs(particleAssoc.pdgCode()) != kKPlus) && (std::abs(particleAssoc.pdgCode()) != kProton)) { continue; @@ -583,7 +595,7 @@ struct HfCorrelatorDplusHadrons { entryDplusHadronRecoInfo(MassDPlus, true); entryDplusHadronGenInfo(isDplusPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); } // end associated loop - } // end trigger + } // end trigger registry.fill(HIST("hcountDplusHadronPerEvent"), counterDplusHadron); registry.fill(HIST("hZvtx"), mcCollision.posZ()); // registry.fill(HIST("hMultiplicity"), getTracksSize(mcCollision)); @@ -623,11 +635,11 @@ struct HfCorrelatorDplusHadrons { continue; } // Dplus flag - bool flagDplusSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; + bool isDplusSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::DplusToPiKPi); // prompt and non-prompt division bool isDplusPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; bool isDplusNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; - if (flagDplusSignal) { + if (isDplusSignal) { if (isDplusPrompt) { registry.fill(HIST("hPtCandMcRecSigPrompt"), candidate.pt()); registry.fill(HIST("hPtVsMultiplicityMcRecPrompt"), candidate.pt(), 0); @@ -661,7 +673,7 @@ struct HfCorrelatorDplusHadrons { std::vector outputMl = {-1., -1., -1.}; bool isPhysicalPrimary = false; int trackOrigin = -1; - bool flagDplusSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; + bool isDplusSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; // prompt and non-prompt division bool isDplusPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; if (pAssoc.has_mcParticle()) { @@ -676,7 +688,7 @@ struct HfCorrelatorDplusHadrons { candidate.pt(), pAssoc.pt(), poolBin); - entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), flagDplusSignal); + entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), isDplusSignal); entryDplusHadronGenInfo(isDplusPrompt, isPhysicalPrimary, trackOrigin); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; diff --git a/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx new file mode 100644 index 00000000000..91bc73c3edd --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx @@ -0,0 +1,251 @@ +// 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 correlatorHfeHadrons.cxx +/// \brief Heavy Flavour electron-Hadron correaltor task - data-like, MC-reco and MC-Kine analyses. +/// \author Rashi Gupta , IIT Indore +/// \author Ravindra Singh , IIT Indore + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.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 "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/HFL/DataModel/ElectronSelectionTable.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; +using namespace o2::aod::hf_sel_electron; + +// definition of ME variables and new types +std::vector zBins{VARIABLE_WIDTH, -10.0, -2.5, 2.5, 10.0}; +std::vector multBins{VARIABLE_WIDTH, 0., 200., 500.0, 5000.}; +std::vector multBinsMcGen{VARIABLE_WIDTH, 0., 20., 50.0, 500.}; // In MCGen multiplicity is defined by counting primaries +using BinningType = ColumnBinningPolicy>; +BinningType corrBinning{{zBins, multBins}, true}; + +struct HfCorrelatorHfeHadrons { + SliceCache cache; + Produces entryElectronHadronPair; + // Configurables + // Event Selection + Configurable zPvPosMax{"zPvPosMax", 10., "Maximum z of the primary vertex (cm)"}; + Configurable isRun3{"isRun3", true, "Data is from Run3 or Run2"}; + + // Associated Hadron selection + Configurable ptTrackMin{"ptTrackMin", 0.1f, "Transverse momentum range for associated hadron tracks"}; + Configurable etaTrackMax{"etaTrackMax", 0.8f, "Eta range for associated hadron tracks"}; + Configurable etaTrackMin{"etaTrackMin", -0.8f, "Eta range for associated hadron tracks"}; + Configurable dcaXYTrackMax{"dcaXYTrackMax", 0.5f, "DCA XY cut"}; + Configurable dcaZTrackMax{"dcaZTrackMax", 1.0f, "DCA Z cut"}; + + // Electron hadron correlation condition + Configurable ptCondition{"ptCondition", true, "Electron pT should be greater than associate particle pT"}; + + using TableCollisions = o2::soa::Filtered>; + using TableCollision = TableCollisions::iterator; + using TableTracks = o2::soa::Join; + + using McTableCollisions = o2::soa::Filtered>; + using McTableCollision = McTableCollisions::iterator; + using McTableTracks = soa::Join; + + Filter CollisionFilter = nabs(aod::collision::posZ) < zPvPosMax && aod::collision::numContrib > (uint16_t)1; + Preslice perCol = aod::track::collisionId; + Preslice perCollision = aod::hf_sel_electron::collisionId; + HistogramConfigSpec hCorrelSpec{HistType::kTHnSparseD, {{30, 0., 30.}, {20, 0., 20.}, {32, -o2::constants::math::PIHalf, 3. * o2::constants::math::PIHalf}, {50, -1.8, 1.8}}}; + + HistogramRegistry registry{ + "registry", + {{"hInclusiveEHCorrel", "Sparse for Delta phi and Delta eta Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;", hCorrelSpec}, + {"hptElectron", "hptElectron", {HistType::kTH1F, {{100, 0, 100}}}}, + {"hMixEventInclusiveEHCorrl", "Sparse for mix event Delta phi and Delta eta Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;", hCorrelSpec}}}; + + void init(InitContext&) + { + registry.get(HIST("hInclusiveEHCorrel"))->Sumw2(); + registry.get(HIST("hMixEventInclusiveEHCorrl"))->Sumw2(); + } + + // Associated Hadron Selection Cut + template + bool selAssoHadron(T const& track) + { + if (!track.isGlobalTrackWoDCA()) { + return false; + } + + if (std::abs(track.dcaXY()) > dcaXYTrackMax || std::abs(track.dcaZ()) > dcaZTrackMax) { + return false; + } + if (track.eta() < etaTrackMin || track.eta() > etaTrackMax) { + return false; + } + if (track.pt() < ptTrackMin) { + return false; + } + return true; + } + + // Electron-hadron Correlation + template + void fillCorrelation(CollisionType const& collision, ElectronType const& electron, TracksType const& tracks) + { + if (!(isRun3 ? collision.sel8() : (collision.sel7() && collision.alias_bit(kINT7)))) + return; + int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFV0M())); + + // Construct Deta Phi between electrons and hadrons + + double ptElectron = -999; + double phiElectron = -999; + double etaElectron = -999; + + for (const auto& eTrack : electron) { + ptElectron = eTrack.ptTrack(); + phiElectron = eTrack.phiTrack(); + etaElectron = eTrack.etaTrack(); + double deltaPhi = -999; + double deltaEta = -999; + double ptHadron = -999; + double etaHadron = -999; + double phiHadron = -999; + if (!eTrack.isEmcal()) + continue; + + registry.fill(HIST("hptElectron"), ptElectron); + for (const auto& hTrack : tracks) { + + if (hTrack.globalIndex() == eTrack.globalIndex()) + continue; + // Apply Hadron cut + if (!selAssoHadron(hTrack)) + continue; + ptHadron = hTrack.pt(); + phiHadron = hTrack.phi(); + etaHadron = hTrack.eta(); + + if (ptCondition && (ptElectron < ptHadron)) + continue; + deltaPhi = RecoDecay::constrainAngle(phiElectron - phiHadron, -o2::constants::math::PIHalf); + deltaEta = etaElectron - etaHadron; + registry.fill(HIST("hInclusiveEHCorrel"), ptElectron, ptHadron, deltaPhi, deltaEta); + entryElectronHadronPair(deltaPhi, deltaEta, ptElectron, ptHadron, poolBin); + } + } + } + + // mix event electron-hadron correlation + + template + void fillMixCorrelation(CollisionType1 const& c1, CollisionType2 const& c2, ElectronType const& tracks1, TracksType const& tracks2) + { + if (!(isRun3 ? c2.sel8() : (c2.sel7() && c2.alias_bit(kINT7)))) + return; + double ptElectronMix = -999; + double phiElectronMix = -999; + double etaElectronMix = -999; + double deltaPhiMix = -999; + double deltaEtaMix = -999; + double ptHadronMix = -999; + double etaHadronMix = -999; + double phiHadronMix = -999; + int poolBin = corrBinning.getBin(std::make_tuple(c2.posZ(), c2.multFV0M())); + for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (!t1.isEmcal()) + continue; + ptHadronMix = t2.pt(); + ptElectronMix = t1.ptTrack(); + phiElectronMix = t1.phiTrack(); + phiHadronMix = t2.phi(); + etaElectronMix = t1.etaTrack(); + etaHadronMix = t2.eta(); + if (!selAssoHadron(t2)) + continue; + if (ptCondition && (ptElectronMix < ptHadronMix)) + continue; + deltaPhiMix = RecoDecay::constrainAngle(phiElectronMix - phiHadronMix, -o2::constants::math::PIHalf); + deltaEtaMix = etaElectronMix - etaHadronMix; + + registry.fill(HIST("hMixEventInclusiveEHCorrl"), ptElectronMix, ptHadronMix, deltaPhiMix, deltaEtaMix); + entryElectronHadronPair(deltaPhiMix, deltaEtaMix, ptElectronMix, ptHadronMix, poolBin); + } + } + + // ======= Process starts for Data, Same event ============ + + void processData(TableCollision const& collision, + aod::HfSelEl const& electron, + TableTracks const& tracks) + { + fillCorrelation(collision, electron, tracks); + } + + PROCESS_SWITCH(HfCorrelatorHfeHadrons, processData, "Process for Data", true); + + // ======= Process starts for McRec, Same event ============ + + void processMcRec(McTableCollision const& mcCollision, + aod::HfSelEl const& mcElectron, + McTableTracks const& mcTracks) + { + fillCorrelation(mcCollision, mcElectron, mcTracks); + } + + PROCESS_SWITCH(HfCorrelatorHfeHadrons, processMcRec, "Process MC Reco mode", false); + + // ====================== Implement Event mixing on Data =================================== + + void processDataMixedEvent(TableCollisions const& collision, aod::HfSelEl const& electron, TableTracks const& tracks) + { + auto tracksTuple = std::make_tuple(electron, tracks); + Pair pair{corrBinning, 5, -1, collision, tracksTuple, &cache}; + + // loop over the rows of the new table + for (auto& [c1, tracks1, c2, tracks2] : pair) { + + fillMixCorrelation(c1, c2, tracks1, tracks2); + } + } + PROCESS_SWITCH(HfCorrelatorHfeHadrons, processDataMixedEvent, "Process Mixed Event Data", false); + + // ====================== Implement Event mixing on McRec =================================== + + void processMcRecMixedEvent(McTableCollisions const& mccollision, aod::HfSelEl const& electron, McTableTracks const& mcTracks) + { + auto tracksTuple = std::make_tuple(electron, mcTracks); + Pair pairMcRec{corrBinning, 5, -1, mccollision, tracksTuple, &cache}; + + // loop over the rows of the new table + for (auto& [c1, tracks1, c2, tracks2] : pairMcRec) { + + fillMixCorrelation(c1, c2, tracks1, tracks2); + } + } + PROCESS_SWITCH(HfCorrelatorHfeHadrons, processMcRecMixedEvent, "Process Mixed Event MC Reco mode", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/Tasks/CMakeLists.txt b/PWGHF/HFC/Tasks/CMakeLists.txt index 2580d9ff75e..ec2e1779ebf 100644 --- a/PWGHF/HFC/Tasks/CMakeLists.txt +++ b/PWGHF/HFC/Tasks/CMakeLists.txt @@ -44,6 +44,11 @@ o2physics_add_dpl_workflow(task-correlation-dstar-hadrons PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-correlation-hfe-hadrons + SOURCES taskCorrelationHfeHadrons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-correlation-lc-hadrons SOURCES taskCorrelationLcHadrons.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/Tasks/taskCorrelationHfeHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationHfeHadrons.cxx new file mode 100644 index 00000000000..5f63948b769 --- /dev/null +++ b/PWGHF/HFC/Tasks/taskCorrelationHfeHadrons.cxx @@ -0,0 +1,68 @@ +// 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 taskCorrelationHfeHadrons.cxx +/// \brief HFE-Hadrons azimuthal correlations analysis task - data-like, MC-reco and MC-Gen analyses +/// \author Rashi Gupta , IIT Indore +/// \author Ravindra Singh , IIT Indore + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/RecoDecay.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::hf_correlation_electron_hadron; + +struct HfTaskCorrelationHfeHadrons { + // Configurables + // Deltaphi binning + Configurable nBinsDeltaPhi{"nBinsDeltaPhi", 32, "Bins for #Delta#varphi bins"}; + + HistogramConfigSpec hCorrelSpec{HistType::kTHnSparseD, {{30, 0., 30.}, {20, 0., 20.}, {nBinsDeltaPhi, -o2::constants::math::PIHalf, 3. * o2::constants::math::PIHalf}, {50, -1.8, 1.8}}}; + + HistogramRegistry registry{ + "registry", + {{"hInclusiveEHCorrel", "Sparse for Delta phi and Delta eta Hadron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;", hCorrelSpec}}}; + + void init(InitContext&) + { + registry.get(HIST("hInclusiveEHCorrel"))->Sumw2(); + } + + // correlation for electron hadron + void process(aod::HfEHadronPair const& pairEntries) + { + double deltaPhi = -999; + double deltaEta = -999; + double ptHadron = -999; + double ptElectron = -999; + + for (const auto& pairEntry : pairEntries) { + + deltaPhi = pairEntry.deltaPhi(); + deltaEta = pairEntry.deltaEta(); + ptElectron = pairEntry.ptElectron(); + ptHadron = pairEntry.ptHadron(); + + registry.fill(HIST("hInclusiveEHCorrel"), ptElectron, ptHadron, deltaPhi, deltaEta); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/TableProducer/candidateSelectorD0.cxx b/PWGHF/TableProducer/candidateSelectorD0.cxx index 3254d513237..ce2b7e9f1bf 100644 --- a/PWGHF/TableProducer/candidateSelectorD0.cxx +++ b/PWGHF/TableProducer/candidateSelectorD0.cxx @@ -26,6 +26,7 @@ #include "PWGHF/Core/HfMlResponseD0ToKPi.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" using namespace o2; using namespace o2::analysis; @@ -72,6 +73,8 @@ struct HfCandidateSelectorD0 { Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_D0ToKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; 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"}; + // Mass Cut for trigger analysis + Configurable useTriggerMassCut{"useTriggerMassCut", false, "Flag to enable parametrize pT differential mass cut for triggered data"}; o2::analysis::HfMlResponseD0ToKPi hfMlResponse; std::vector outputMlD0 = {}; @@ -80,6 +83,7 @@ struct HfCandidateSelectorD0 { TrackSelectorPi selectorPion; TrackSelectorKa selectorKaon; HfHelper hfHelper; + HfTrigger2ProngCuts hfTriggerCuts; using TracksSel = soa::Join; @@ -158,7 +162,9 @@ struct HfCandidateSelectorD0 { return false; } // candidate DCA - // if (candidate.chi2PCA() > cuts[pTBin][1]) return false; + if (candidate.impactParameterXY() > cuts->get(pTBin, "DCA")) { + return false; + } // candidate topological chi2 over ndf when using KFParticle, need to add this selection to the SelectorCuts.h // if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { @@ -209,10 +215,16 @@ struct HfCandidateSelectorD0 { if (std::abs(massD0 - o2::constants::physics::MassD0) > cuts->get(pTBin, "m")) { return false; } + if (useTriggerMassCut && !isCandidateInMassRange(massD0, o2::constants::physics::MassD0, candidate.pt(), hfTriggerCuts)) { + return false; + } } else { if (std::abs(massD0bar - o2::constants::physics::MassD0) > cuts->get(pTBin, "m")) { return false; } + if (useTriggerMassCut && !isCandidateInMassRange(massD0bar, o2::constants::physics::MassD0, candidate.pt(), hfTriggerCuts)) { + return false; + } } // cut on daughter pT diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 6ade0108040..fe77bb275d9 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -2962,10 +2962,8 @@ struct HfTrackIndexSkimCreatorCascades { struct : ConfigurableGroup { Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; Configurable fillHistograms{"fillHistograms", true, "fill histograms"}; - // event selection - // Configurable triggerindex{"triggerindex", -1, "trigger index"}; // vertexing - // Configurable bz{"bz", 5., "magnetic field"}; + Configurable useDCAFitter{"useDCAFitter", true, "flag to optionally turn on/off the vertex reconstruction with the DCAFitter"}; Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; @@ -2973,24 +2971,12 @@ struct HfTrackIndexSkimCreatorCascades { Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; Configurable useWeightedFinalPCA{"useWeightedFinalPCA", true, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; - // quality cut - Configurable doCutQuality{"doCutQuality", true, "apply quality cuts"}; - // track cuts for bachelor - Configurable tpcRefitBach{"tpcRefitBach", true, "request TPC refit bachelor"}; - Configurable nCrossedRowsMinBach{"nCrossedRowsMinBach", 50, "min crossed rows bachelor"}; // track cuts for V0 daughters - Configurable tpcRefitV0Daugh{"tpcRefitV0Daugh", true, "request TPC refit V0 daughters"}; - Configurable nCrossedRowsMinV0Daugh{"nCrossedRowsMinV0Daugh", 50, "min crossed rows V0 daughters"}; Configurable etaMinV0Daugh{"etaMinV0Daugh", -99999., "min. pseudorapidity V0 daughters"}; Configurable etaMaxV0Daugh{"etaMaxV0Daugh", 1.1, "max. pseudorapidity V0 daughters"}; Configurable ptMinV0Daugh{"ptMinV0Daugh", 0.05, "min. pT V0 daughters"}; - // bachelor cuts - // Configurable dcabachtopv{"dcabachtopv", .1, "DCA Bach To PV"}; - // Configurable ptminbach{"ptminbach", -1., "min. track pT bachelor"}; // v0 cuts - Configurable cpaV0Min{"cpaV0Min", .995, "min. cos PA V0"}; // as in the task that create the V0s - Configurable dcaXYNegToPvMin{"dcaXYNegToPvMin", .1, "min. DCA_XY Neg To PV"}; // check: in HF Run 2, it was 0 at filtering - Configurable dcaXYPosToPvMin{"dcaXYPosToPvMin", .1, "min. DCA_XY Pos To PV"}; // check: in HF Run 2, it was 0 at filtering + Configurable cpaV0Min{"cpaV0Min", 0.95, "min. cos PA V0"}; // as in the task that create the V0s Configurable cutInvMassV0{"cutInvMassV0", 0.05, "V0 candidate invariant mass difference wrt PDG"}; // cascade cuts Configurable ptCascCandMin{"ptCascCandMin", -1., "min. pT of the cascade candidate"}; // PbPb 2018: use 1 @@ -3011,11 +2997,11 @@ struct HfTrackIndexSkimCreatorCascades { Service ccdb; o2::base::MatLayerCylSet* lut; o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - int runNumber; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + int runNumber{0}; double massP{0.}; double massK0s{0.}; - double massPi{0.}; double massLc{0.}; using SelectedCollisions = soa::Filtered>; @@ -3042,23 +3028,22 @@ struct HfTrackIndexSkimCreatorCascades { massP = o2::constants::physics::MassProton; massK0s = o2::constants::physics::MassK0Short; - massPi = o2::constants::physics::MassPiPlus; massLc = o2::constants::physics::MassLambdaCPlus; - df2.setPropagateToPCA(config.propagateToPCA); - df2.setMaxR(config.maxR); - df2.setMinParamChange(config.minParamChange); - df2.setMinRelChi2Change(config.minRelChi2Change); - // df2.setMaxDZIni(1e9); // used in cascadeproducer.cxx, but not for the 2 prongs - // df2.setMaxChi2(1e9); // used in cascadeproducer.cxx, but not for the 2 prongs - df2.setUseAbsDCA(config.useAbsDCA); - df2.setWeightedFinalPCA(config.useWeightedFinalPCA); + if (config.useDCAFitter) { + df2.setPropagateToPCA(config.propagateToPCA); + df2.setMaxR(config.maxR); + df2.setMinParamChange(config.minParamChange); + df2.setMinRelChi2Change(config.minRelChi2Change); + df2.setMaxDZIni(config.maxDZIni); + df2.setUseAbsDCA(config.useAbsDCA); + df2.setWeightedFinalPCA(config.useWeightedFinalPCA); + } ccdb->setURL(config.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(config.ccdbPathLut)); - runNumber = 0; if (config.fillHistograms) { registry.add("hVtx2ProngX", "2-prong candidates;#it{x}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -2., 2.}}}); @@ -3075,7 +3060,7 @@ struct HfTrackIndexSkimCreatorCascades { PROCESS_SWITCH(HfTrackIndexSkimCreatorCascades, processNoCascades, "Do not skim HF -> V0 cascades", true); void processCascades(SelectedCollisions const& collisions, - aod::V0Datas const& v0s, + soa::Join const& v0s, FilteredTrackAssocSel const& trackIndices, aod::TracksWCovDcaExtra const&, aod::BCsWithTimestamps const&) @@ -3084,67 +3069,52 @@ struct HfTrackIndexSkimCreatorCascades { for (const auto& collision : collisions) { auto bc = collision.bc_as(); initCCDB(bc, runNumber, ccdb, config.isRun2 ? config.ccdbPathGrp : config.ccdbPathGrpMag, lut, config.isRun2); - df2.setBz(o2::base::Propagator::Instance()->getNominalBz()); - - // fist we loop over the bachelor candidate + if (config.useDCAFitter) { + df2.setBz(o2::base::Propagator::Instance()->getNominalBz()); + df2.setMatCorrType(matCorr); + } const auto thisCollId = collision.globalIndex(); auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + auto groupedV0s = v0s.sliceBy(v0sPerCollision, thisCollId); - // for (const auto& bach : selectedTracks) { + // fist we loop over the bachelor candidate for (const auto& bachIdx : groupedBachTrackIndices) { auto bach = bachIdx.track_as(); - - // selections on the bachelor - - // pT cut - // FIXME: this should go in the tag-sel-tracks - if (config.tpcRefitBach) { - if (!(bach.trackType() & o2::aod::track::TPCrefit)) { - continue; - } - } - if (bach.tpcNClsCrossedRows() < config.nCrossedRowsMinBach) { - continue; - } - + std::array pVecBach{bach.pVector()}; auto trackBach = getTrackParCov(bach); + if (thisCollId != bach.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it + o2::gpu::gpustd::array dcaInfoBach{bach.dcaXY(), bach.dcaZ()}; + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackBach, 2.f, noMatCorr, &dcaInfoBach); + getPxPyPz(trackBach, pVecBach); + } - auto groupedV0s = v0s.sliceBy(v0sPerCollision, thisCollId); // now we loop over the V0s for (const auto& v0 : groupedV0s) { // selections on the V0 daughters - const auto& trackV0DaughPos = v0.posTrack_as(); - const auto& trackV0DaughNeg = v0.negTrack_as(); + const auto& trackV0DaughPos = v0.posTrack_as(); // only used for indices and track cuts (TPC clusters, TPC refit) + const auto& trackV0DaughNeg = v0.negTrack_as(); // only used for indices and track cuts (TPC clusters, TPC refit) // check not to take the same track twice (as bachelor and V0 daughter) if (trackV0DaughPos.globalIndex() == bach.globalIndex() || trackV0DaughNeg.globalIndex() == bach.globalIndex()) { continue; } - if (config.tpcRefitV0Daugh) { - if (!(trackV0DaughPos.trackType() & o2::aod::track::TPCrefit) || - !(trackV0DaughNeg.trackType() & o2::aod::track::TPCrefit)) { - continue; - } - } - if (trackV0DaughPos.tpcNClsCrossedRows() < config.nCrossedRowsMinV0Daugh || - trackV0DaughNeg.tpcNClsCrossedRows() < config.nCrossedRowsMinV0Daugh) { - continue; - } - // - // if (trackV0DaughPos.dcaXY() < dcaXYPosToPvMin || // to the filters? - // trackV0DaughNeg.dcaXY() < dcaXYNegToPvMin) { - // continue; - // } - // - if (trackV0DaughPos.pt() < config.ptMinV0Daugh || // to the filters? I can't for now, it is not in the tables - trackV0DaughNeg.pt() < config.ptMinV0Daugh) { + std::array pVecPos = {v0.pxpos(), v0.pypos(), v0.pzpos()}; + std::array pVecNeg = {v0.pxneg(), v0.pyneg(), v0.pzneg()}; + + float ptPos = RecoDecay::pt(pVecPos); + float ptNeg = RecoDecay::pt(pVecNeg); + if (ptPos < config.ptMinV0Daugh || // to the filters? I can't for now, it is not in the tables + ptNeg < config.ptMinV0Daugh) { continue; } - if ((trackV0DaughPos.eta() > config.etaMaxV0Daugh || trackV0DaughPos.eta() < config.etaMinV0Daugh) || // to the filters? I can't for now, it is not in the tables - (trackV0DaughNeg.eta() > config.etaMaxV0Daugh || trackV0DaughNeg.eta() < config.etaMinV0Daugh)) { + + float etaPos = RecoDecay::eta(pVecPos); + float etaNeg = RecoDecay::eta(pVecNeg); + if ((etaPos > config.etaMaxV0Daugh || etaPos < config.etaMinV0Daugh) || // to the filters? I can't for now, it is not in the tables + (etaNeg > config.etaMaxV0Daugh || etaNeg < config.etaMinV0Daugh)) { continue; } @@ -3158,40 +3128,44 @@ struct HfTrackIndexSkimCreatorCascades { continue; } - const std::array momentumV0 = {v0.px(), v0.py(), v0.pz()}; + std::array pVecV0 = {v0.px(), v0.py(), v0.pz()}; // invariant-mass cut: we do it here, before updating the momenta of bach and V0 during the fitting to save CPU // TODO: but one should better check that the value here and after the fitter do not change significantly!!! - double mass2K0sP = RecoDecay::m(std::array{bach.pVector(), momentumV0}, std::array{massP, massK0s}); + double mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{massP, massK0s}); if ((config.cutInvMassCascLc >= 0.) && (std::abs(mass2K0sP - massLc) > config.cutInvMassCascLc)) { continue; } - auto trackParCovV0DaughPos = getTrackParCov(trackV0DaughPos); - trackParCovV0DaughPos.propagateTo(v0.posX(), o2::base::Propagator::Instance()->getNominalBz()); // propagate the track to the X closest to the V0 vertex - auto trackParCovV0DaughNeg = getTrackParCov(trackV0DaughNeg); - trackParCovV0DaughNeg.propagateTo(v0.negX(), o2::base::Propagator::Instance()->getNominalBz()); // propagate the track to the X closest to the V0 vertex - std::array pVecV0 = {0., 0., 0.}; - std::array pVecBach = {0., 0., 0.}; - - const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; - // we build the neutral track to then build the cascade - auto trackV0 = o2::dataformats::V0(vertexV0, momentumV0, {0, 0, 0, 0, 0, 0}, trackParCovV0DaughPos, trackParCovV0DaughNeg); // build the V0 track - // now we find the DCA between the V0 and the bachelor, for the cascade - int nCand2 = 0; - try { - nCand2 = df2.process(trackV0, trackBach); - } catch (...) { - continue; - } + if (config.useDCAFitter) { + + const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; + // we build the neutral track to then build the cascade + std::array covV = {0.}; + constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + for (int i = 0; i < 6; i++) { + covV[MomInd[i]] = v0.momentumCovMat()[i]; + covV[i] = v0.positionCovMat()[i]; + } + auto trackV0 = o2::track::TrackParCov(vertexV0, pVecV0, covV, 0, true); + trackV0.setAbsCharge(0); + trackV0.setPID(o2::track::PID::K0); - if (nCand2 == 0) { - continue; + int nCand2 = 0; + try { + nCand2 = df2.process(trackV0, trackBach); + } catch (...) { + continue; + } + + if (nCand2 == 0) { + continue; + } + df2.propagateTracksToVertex(); // propagate the bach and V0 to the Lc vertex + df2.getTrack(0).getPxPyPzGlo(pVecV0); // take the momentum at the Lc vertex + df2.getTrack(1).getPxPyPzGlo(pVecBach); } - df2.propagateTracksToVertex(); // propagate the bach and V0 to the Lc vertex - df2.getTrack(0).getPxPyPzGlo(pVecV0); // take the momentum at the Lc vertex - df2.getTrack(1).getPxPyPzGlo(pVecBach); // cascade candidate pT cut auto ptCascCand = RecoDecay::pt(pVecBach, pVecV0); @@ -3202,11 +3176,12 @@ struct HfTrackIndexSkimCreatorCascades { // invariant mass // re-calculate invariant masses with updated momenta, to fill the histogram mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{massP, massK0s}); - std::array posCasc = {0., 0., 0.}; - const auto& cascVtx = df2.getPCACandidate(); - for (int i = 0; i < 3; i++) { - posCasc[i] = cascVtx[i]; + if (config.useDCAFitter) { + const auto& cascVtx = df2.getPCACandidate(); + for (int iCoord{0}; iCoord < 3; ++iCoord) { + posCasc[iCoord] = cascVtx[iCoord]; + } } // fill table row diff --git a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx index d9efc0202a7..f0c1c1503c2 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -244,15 +244,12 @@ DECLARE_SOA_TABLE(HfCandLcFullEvs, "AOD", "HFCANDLCFULLEV", full::MultZeqNTracksPV); DECLARE_SOA_TABLE(HfCandLcFullPs, "AOD", "HFCANDLCFULLP", - full::McCollisionId, full::Pt, full::Eta, full::Phi, full::Y, full::FlagMc, - full::OriginMcGen, - full::McParticleId); - + full::OriginMcGen); } // namespace o2::aod /// Writes the full information in an output TTree @@ -502,14 +499,12 @@ struct HfTreeCreatorLcToPKPi { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { rowCandidateFullParticles( - particle.mcCollisionId(), particle.pt(), particle.eta(), particle.phi(), RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus), particle.flagMcMatchGen(), - particle.originMcGen(), - particle.globalIndex()); + particle.originMcGen()); } } } diff --git a/PWGJE/Core/JetUtilities.h b/PWGJE/Core/JetUtilities.h index a681d76bf89..dac55dfbaa1 100644 --- a/PWGJE/Core/JetUtilities.h +++ b/PWGJE/Core/JetUtilities.h @@ -141,12 +141,20 @@ std::tuple>, std::vector>> MatchCl template float deltaR(T const& A, U const& B) { - float dPhi = RecoDecay::constrainAngle(A.phi() - B.phi(), -M_PI); + float dPhi = RecoDecay::constrainAngle(RecoDecay::constrainAngle(A.phi(), -M_PI) - RecoDecay::constrainAngle(B.phi(), -M_PI), -M_PI); float dEta = A.eta() - B.eta(); - return TMath::Sqrt(dEta * dEta + dPhi * dPhi); + return std::sqrt(dEta * dEta + dPhi * dPhi); } +// same as deltaR but explicit specification of the eta and phi components +template +float deltaR(T const& eta1, U const& phi1, V const& eta2, W const& phi2) +{ + float dPhi = RecoDecay::constrainAngle(RecoDecay::constrainAngle(phi1, -M_PI) - RecoDecay::constrainAngle(phi2, -M_PI), -M_PI); + float dEta = eta1 - eta2; + return std::sqrt(dEta * dEta + dPhi * dPhi); +} }; // namespace jetutilities #endif // PWGJE_CORE_JETUTILITIES_H_ diff --git a/PWGJE/DataModel/GammaJetAnalysisTree.h b/PWGJE/DataModel/GammaJetAnalysisTree.h new file mode 100644 index 00000000000..beb927f381c --- /dev/null +++ b/PWGJE/DataModel/GammaJetAnalysisTree.h @@ -0,0 +1,75 @@ +// 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. + +/// +/// \brief Table definitions for gamma-jet analyses +/// +/// \author Florian Jonas + +#ifndef PWGJE_DATAMODEL_GAMMAJETANALYSISTREE_H_ +#define PWGJE_DATAMODEL_GAMMAJETANALYSISTREE_H_ + +#include "Framework/AnalysisDataModel.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/DataModel/Jet.h" + +namespace o2::aod +{ + +namespace gjevent +{ // TODO add rho //! event index +DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); +DECLARE_SOA_COLUMN(Centrality, centrality, float); +DECLARE_SOA_COLUMN(Rho, rho, float); +DECLARE_SOA_COLUMN(EventSel, eventSel, uint8_t); +DECLARE_SOA_BITMAP_COLUMN(Alias, alias, 32); +} // namespace gjevent +DECLARE_SOA_TABLE(GjEvents, "AOD", "GJEVENT", o2::soa::Index<>, gjevent::Multiplicity, gjevent::Centrality, gjevent::Rho, gjevent::EventSel, gjevent::Alias) + +using GjEvent = GjEvents::iterator; + +namespace gjgamma +{ +DECLARE_SOA_INDEX_COLUMN(GjEvent, gjevent); //! event index +DECLARE_SOA_COLUMN(Energy, energy, float); //! cluster energy (GeV) +DECLARE_SOA_COLUMN(Eta, eta, float); //! cluster pseudorapidity (calculated using vertex) +DECLARE_SOA_COLUMN(Phi, phi, float); //! cluster azimuthal angle (calculated using vertex) +DECLARE_SOA_COLUMN(M02, m02, float); //! shower shape long axis +DECLARE_SOA_COLUMN(M20, m20, float); //! shower shape short axis +DECLARE_SOA_COLUMN(NCells, nCells, ushort); //! number of cells in cluster +DECLARE_SOA_COLUMN(Time, time, float); //! cluster time (ns) +DECLARE_SOA_COLUMN(IsExotic, isExotic, bool); //! flag to mark cluster as exotic +DECLARE_SOA_COLUMN(DistanceToBadChannel, distanceToBadChannel, float); //! distance to bad channel +DECLARE_SOA_COLUMN(NLM, nlm, ushort); //! number of local maxima +DECLARE_SOA_COLUMN(IsoRaw, isoraw, ushort); //! isolation in cone not corrected for Rho +DECLARE_SOA_COLUMN(PerpConeRho, perpconerho, float); //! rho in perpendicular cone +DECLARE_SOA_COLUMN(TMdeltaPhi, tmdeltaphi, float); //! delta phi between cluster and closest match +DECLARE_SOA_COLUMN(TMdeltaEta, tmdeltaeta, float); //! delta eta between cluster and closest match +DECLARE_SOA_COLUMN(TMtrackP, tmtrackp, float); //! track momentum of closest match, -1 if no match found +} // namespace gjgamma +DECLARE_SOA_TABLE(GjGammas, "AOD", "GJGAMMA", + gjgamma::GjEventId, gjgamma::Energy, gjgamma::Eta, gjgamma::Phi, gjgamma::M02, gjgamma::M20, gjgamma::NCells, gjgamma::Time, gjgamma::IsExotic, gjgamma::DistanceToBadChannel, gjgamma::NLM, gjgamma::IsoRaw, gjgamma::PerpConeRho, gjgamma::TMdeltaPhi, gjgamma::TMdeltaEta, gjgamma::TMtrackP) +namespace gjchjet +{ +DECLARE_SOA_INDEX_COLUMN(GjEvent, gjevent); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(Phi, phi, float); +DECLARE_SOA_COLUMN(Energy, energy, float); +DECLARE_SOA_COLUMN(Mass, mass, float); +DECLARE_SOA_COLUMN(Area, area, float); +DECLARE_SOA_COLUMN(NConstituents, nConstituents, ushort); +} // namespace gjchjet +DECLARE_SOA_TABLE(GjChargedJets, "AOD", "GJCHJET", gjchjet::GjEventId, gjchjet::Pt, gjchjet::Eta, gjchjet::Phi, gjchjet::Energy, gjchjet::Mass, gjchjet::Area, gjchjet::NConstituents) +} // namespace o2::aod + +#endif // PWGJE_DATAMODEL_GAMMAJETANALYSISTREE_H_ diff --git a/PWGJE/DataModel/JetSubtraction.h b/PWGJE/DataModel/JetSubtraction.h index 639049ea81a..f789d18637a 100644 --- a/PWGJE/DataModel/JetSubtraction.h +++ b/PWGJE/DataModel/JetSubtraction.h @@ -63,33 +63,32 @@ DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, Dielectrons, "_0"); DECLARE_SOA_TABLE(BkgChargedRhos, "AOD", "BkgCRho", o2::soa::Index<>, - bkgcharged::JCollisionId, bkgrho::Rho, bkgrho::RhoM); DECLARE_SOA_TABLE(BkgD0Rhos, "AOD", "BkgD0Rho", o2::soa::Index<>, - bkgd0::CandidateId, bkgrho::Rho, - bkgrho::RhoM); + bkgrho::RhoM, + o2::soa::Marker<1>); DECLARE_SOA_TABLE(BkgLcRhos, "AOD", "BkgLcRho", o2::soa::Index<>, - bkglc::CandidateId, bkgrho::Rho, - bkgrho::RhoM); + bkgrho::RhoM, + o2::soa::Marker<2>); DECLARE_SOA_TABLE(BkgBplusRhos, "AOD", "BkgBPlRho", o2::soa::Index<>, - bkgbplus::CandidateId, bkgrho::Rho, - bkgrho::RhoM); + bkgrho::RhoM, + o2::soa::Marker<3>); DECLARE_SOA_TABLE(BkgDielectronRhos, "AOD", "BkgDIELRho", o2::soa::Index<>, - bkgdielectron::CandidateId, bkgrho::Rho, - bkgrho::RhoM); + bkgrho::RhoM, + o2::soa::Marker<4>); namespace jtracksub { diff --git a/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx b/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx index 6b0376a3e25..a749da6dcd3 100644 --- a/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx +++ b/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx @@ -34,6 +34,7 @@ struct eventWiseConstituentSubtractorTask { Produces trackSubtractedD0Table; Produces trackSubtractedLcTable; Produces trackSubtractedBplusTable; + Produces trackSubtractedDielectronTable; Configurable trackPtMin{"trackPtMin", 0.15, "minimum track pT"}; Configurable trackPtMax{"trackPtMax", 1000.0, "maximum track pT"}; @@ -66,25 +67,16 @@ struct eventWiseConstituentSubtractorTask { Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax && aod::jtrack::phi >= trackPhiMin && aod::jtrack::phi <= trackPhiMax); - Preslice perD0Candidate = aod::bkgd0::candidateId; - Preslice perLcCandidate = aod::bkglc::candidateId; - Preslice perBplusCandidate = aod::bkgbplus::candidateId; - Preslice perDielectronCandidate = aod::bkgdielectron::candidateId; - - template - void analyseHF(T const& tracks, U const& candidates, V const& bkgRhos, M& trackSubtractedTable) + template + void analyseHF(T const& tracks, U const& candidates, V& trackSubtractedTable) { for (auto& candidate : candidates) { - - auto const bkgRhosSliced = jetcandidateutilities::slicedPerCandidate(bkgRhos, candidate, perD0Candidate, perLcCandidate, perBplusCandidate, perDielectronCandidate); - auto const bkgRho = bkgRhosSliced.iteratorAt(0); - inputParticles.clear(); tracksSubtracted.clear(); jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, trackingEfficiency, std::optional{candidate}); - tracksSubtracted = eventWiseConstituentSubtractor.JetBkgSubUtils::doEventConstSub(inputParticles, bkgRho.rho(), bkgRho.rhoM()); + tracksSubtracted = eventWiseConstituentSubtractor.JetBkgSubUtils::doEventConstSub(inputParticles, candidate.rho(), candidate.rhoM()); for (auto const& trackSubtracted : tracksSubtracted) { trackSubtractedTable(candidate.globalIndex(), trackSubtracted.pt(), trackSubtracted.eta(), trackSubtracted.phi(), trackSubtracted.E(), jetderiveddatautilities::setSingleTrackSelectionBit(trackSelection)); @@ -107,23 +99,29 @@ struct eventWiseConstituentSubtractorTask { } PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processCollisions, "Fill table of subtracted tracks for collisions", true); - void processD0Collisions(JetCollision const&, aod::BkgD0Rhos const& bkgRhos, soa::Filtered const& tracks, CandidatesD0Data const& candidates) + void processD0Collisions(JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) { - analyseHF(tracks, candidates, bkgRhos, trackSubtractedD0Table); + analyseHF(tracks, candidates, trackSubtractedD0Table); } PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processD0Collisions, "Fill table of subtracted tracks for collisions with D0 candidates", false); - void processLcCollisions(JetCollision const&, aod::BkgLcRhos const& bkgRhos, soa::Filtered const& tracks, CandidatesLcData const& candidates) + void processLcCollisions(JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) { - analyseHF(tracks, candidates, bkgRhos, trackSubtractedLcTable); + analyseHF(tracks, candidates, trackSubtractedLcTable); } PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processLcCollisions, "Fill table of subtracted tracks for collisions with Lc candidates", false); - void processBplusCollisions(JetCollision const&, aod::BkgBplusRhos const& bkgRhos, soa::Filtered const& tracks, CandidatesBplusData const& candidates) + void processBplusCollisions(JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) { - analyseHF(tracks, candidates, bkgRhos, trackSubtractedBplusTable); + analyseHF(tracks, candidates, trackSubtractedBplusTable); } PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processBplusCollisions, "Fill table of subtracted tracks for collisions with Bplus candidates", false); + + void processDielectronCollisions(JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) + { + analyseHF(tracks, candidates, trackSubtractedDielectronTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processDielectronCollisions, "Fill table of subtracted tracks for collisions with Dielectron candidates", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"subtractor-eventwiseconstituent"})}; } diff --git a/PWGJE/TableProducer/rhoEstimator.cxx b/PWGJE/TableProducer/rhoEstimator.cxx index a5a543125a3..7a5be53476e 100644 --- a/PWGJE/TableProducer/rhoEstimator.cxx +++ b/PWGJE/TableProducer/rhoEstimator.cxx @@ -34,6 +34,7 @@ struct RhoEstimatorTask { Produces rhoD0Table; Produces rhoLcTable; Produces rhoBplusTable; + Produces rhoDielectronTable; Configurable trackPtMin{"trackPtMin", 0.15, "minimum track pT"}; Configurable trackPtMax{"trackPtMax", 1000.0, "maximum track pT"}; @@ -75,7 +76,7 @@ struct RhoEstimatorTask { inputParticles.clear(); jetfindingutilities::analyseTracks, soa::Filtered::iterator>(inputParticles, tracks, trackSelection, trackingEfficiency); auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); - rhoChargedTable(collision.globalIndex(), rho, rhoM); + rhoChargedTable(rho, rhoM); } PROCESS_SWITCH(RhoEstimatorTask, processChargedCollisions, "Fill rho tables for collisions using charged tracks", true); @@ -87,7 +88,7 @@ struct RhoEstimatorTask { jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, trackingEfficiency, std::optional{candidate}); auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); - rhoD0Table(candidate.globalIndex(), rho, rhoM); + rhoD0Table(rho, rhoM); } } PROCESS_SWITCH(RhoEstimatorTask, processD0Collisions, "Fill rho tables for collisions with D0 candidates", false); @@ -100,7 +101,7 @@ struct RhoEstimatorTask { jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, trackingEfficiency, std::optional{candidate}); auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); - rhoLcTable(candidate.globalIndex(), rho, rhoM); + rhoLcTable(rho, rhoM); } } PROCESS_SWITCH(RhoEstimatorTask, processLcCollisions, "Fill rho tables for collisions with Lc candidates", false); @@ -113,10 +114,23 @@ struct RhoEstimatorTask { jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, trackingEfficiency, std::optional{candidate}); auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); - rhoBplusTable(candidate.globalIndex(), rho, rhoM); + rhoBplusTable(rho, rhoM); } } PROCESS_SWITCH(RhoEstimatorTask, processBplusCollisions, "Fill rho tables for collisions with Bplus candidates", false); + + void processDielectronCollisions(JetCollision const&, soa::Filtered const& tracks, CandidatesDielectronData const& candidates) + { + inputParticles.clear(); + for (auto& candidate : candidates) { + inputParticles.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, trackingEfficiency, std::optional{candidate}); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); + rhoDielectronTable(rho, rhoM); + } + } + PROCESS_SWITCH(RhoEstimatorTask, processDielectronCollisions, "Fill rho tables for collisions with Dielectron candidates", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"estimator-rho"})}; } diff --git a/PWGJE/TableProducer/secondaryVertexReconstruction.cxx b/PWGJE/TableProducer/secondaryVertexReconstruction.cxx index 1a6536354a4..1474aafa873 100644 --- a/PWGJE/TableProducer/secondaryVertexReconstruction.cxx +++ b/PWGJE/TableProducer/secondaryVertexReconstruction.cxx @@ -163,7 +163,12 @@ struct SecondaryVertexReconstruction { // Reconstruct the secondary vertex int processResult = 0; - std::apply([&df, &processResult](const auto&... elems) { processResult = df.process(elems...); }, trackParVars); + try { + std::apply([&df, &processResult](const auto&... elems) { processResult = df.process(elems...); }, trackParVars); + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN cannot work, skipping the candidate."; + return; + } if (processResult == 0) { return; } diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index adbd4e141a5..a9ac88c8f28 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -168,6 +168,10 @@ if(FastJet_FOUND) SOURCES fulljetspectrapp.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(gamma-jet-tree-producer + SOURCES gammajettreeproducer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(bjet-tagging-ml SOURCES bjetTaggingML.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2Physics::MLCore diff --git a/PWGJE/Tasks/fulljetspectrapp.cxx b/PWGJE/Tasks/fulljetspectrapp.cxx index de0f94b0494..b93f05ca427 100644 --- a/PWGJE/Tasks/fulljetspectrapp.cxx +++ b/PWGJE/Tasks/fulljetspectrapp.cxx @@ -128,6 +128,8 @@ struct FullJetSpectrapp { h_collisions_unweighted->GetXaxis()->SetBinLabel(7, "JetsMCD w/o kTVXinEMC"); h_collisions_unweighted->GetXaxis()->SetBinLabel(8, "Tracks w/o kTVXinEMC"); h_collisions_unweighted->GetXaxis()->SetBinLabel(9, "JetsMCPMCDMatched w/o kTVXinEMC"); + h_collisions_unweighted->GetXaxis()->SetBinLabel(10, "Fake Matched MCD Jets"); + h_collisions_unweighted->GetXaxis()->SetBinLabel(11, "Fake Matched MCP Jets"); } if (doprocessTracksWeighted) { @@ -163,7 +165,7 @@ struct FullJetSpectrapp { // Track QA histograms if (doprocessTracks || doprocessTracksWeighted) { - registry.add("h_collisions_unweighted", "event status; event status;entries", {HistType::kTH1F, {{11, 0., 11.0}}}); + registry.add("h_collisions_unweighted", "event status; event status;entries", {HistType::kTH1F, {{12, 0., 12.0}}}); 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.}}}); @@ -230,7 +232,7 @@ struct FullJetSpectrapp { 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.}, {100, 0.0, 1.5}}}); + 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.}}}); @@ -305,8 +307,8 @@ struct FullJetSpectrapp { using JetTableMCDMatchedJoined = soa::Join; using JetTableMCPMatchedJoined = soa::Join; - using JetTableMCDMatchedWeightedJoined = soa::Join; - using JetTableMCPMatchedWeightedJoined = soa::Join; + using JetTableMCDMatchedWeightedJoined = soa::Join; + using JetTableMCPMatchedWeightedJoined = soa::Join; // Applying some cuts(filters) on collisions, tracks, clusters @@ -315,6 +317,7 @@ struct FullJetSpectrapp { Filter trackCuts = (aod::jtrack::pt >= trackpTMin && aod::jtrack::pt < trackpTMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax && aod::jtrack::phi >= trackPhiMin && aod::jtrack::phi <= trackPhiMax); aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); 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; template bool isAcceptedJet(U const& jet) @@ -344,7 +347,6 @@ struct FullJetSpectrapp { void fillJetHistograms(T const& jet, float weight = 1.0) { float neutralEnergy = 0.0; - // std::cout << "jet r is " << jet.r() << " its rounded value is " << round(selectedJetsRadius * 100.0f) << std::endl; if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_full_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_full_jet_eta"), jet.eta(), weight); @@ -628,7 +630,7 @@ struct FullJetSpectrapp { registry.fill(HIST("h_collisions_weighted"), 5.0); // JetsMCDWeighted w/o kTVXinEMC for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { - fillRejectedJetHistograms(jet, 1.0); + fillRejectedJetHistograms(jet, jet.eventWeight()); } } return; @@ -644,10 +646,8 @@ struct FullJetSpectrapp { if (!isAcceptedJet(jet)) { continue; } - // std::cout << "jet pT" << jet.pt() << "jet eta"<< jet.eta()<< "jet phi"<< jet.phi()<< std::endl; - // std::cout << "Event weight: " << jet.eventWeight() << std::endl; + fillJetHistograms(jet, jet.eventWeight()); - // std::cout << "jet pT" << jet.pt() << "jet eta"<< jet.eta()<< "jet phi"<< jet.phi()<< std::endl; } } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCDWeighted, "Full Jets at Detector Level on weighted events", false); @@ -672,8 +672,7 @@ struct FullJetSpectrapp { if (!isAcceptedJet(jet)) { return; } - // std::cout << "jet pT" << jet.pt() << "jet eta"<< jet.eta()<< "jet phi"<< jet.phi()<< std::endl; - // std::cout << "Event weight: " << jet.eventWeight() << std::endl; + fillMCPHistograms(jet, jet.eventWeight()); } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPWeighted, "Full Jets at Particle Level on weighted events", false); @@ -718,6 +717,8 @@ struct FullJetSpectrapp { { registry.fill(HIST("h_collisions_unweighted"), 1.0); // total events bool eventAccepted = false; + int fakemcdjet = 0; + int fakemcpjet = 0; if (fabs(collision.posZ()) > VertexZCut) { // making double sure this condition is satisfied return; @@ -746,27 +747,28 @@ struct FullJetSpectrapp { //**end of event selection** for (const auto& mcdjet : mcdjets) { - if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - continue; - } - if (!isAcceptedJet(mcdjet)) { + // Check if MCD jet is within the EMCAL fiducial region + if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { + fakemcdjet++; + registry.fill(HIST("h_collisions_unweighted"), 10.0); // Fake Matched MCD Jets + registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakemcdjet, 1.0); continue; } - if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; } - if (!mcdjet.has_matchedJetGeo()) { + if (!isAcceptedJet(mcdjet)) { continue; } for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - - if (!mcpjet.has_matchedJetGeo()) { - continue; - } // apply emcal fiducial cuts to the matched particle level jets - if (mcpjet.eta() > jetEtaMax || mcpjet.phi() > jetPhiMax || !jetfindingutilities::isInEtaAcceptance(mcpjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { + fakemcpjet++; + registry.fill(HIST("h_collisions_unweighted"), 11.0); // Fake Matched MCP Jets + registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakemcpjet, 1.0); continue; } + // Fill MCD jet histograms if a valid MCP jet match was found within the EMCAL region registry.fill(HIST("h_full_matchedmcpjet_eta"), mcpjet.eta(), 1.0); registry.fill(HIST("h_full_matchedmcpjet_phi"), mcpjet.phi(), 1.0); fillMatchedHistograms(mcdjet); @@ -777,15 +779,21 @@ struct FullJetSpectrapp { } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPMCDMatched, "Full Jet finder MCP matched to MCD", false); - void processJetsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const&, aod::JMcCollisions const&, JetTracks const&, JetClusters const&, JetParticles const&) + void processJetsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const& mcpjets, aod::JMcCollisions const&, JetTracks const&, JetClusters const&, JetParticles const&) { float eventWeight = collision.mcCollision().weight(); registry.fill(HIST("h_collisions_weighted"), 1.0, eventWeight); // total events bool eventAccepted = false; int fakemcdjet = 0; int fakemcpjet = 0; - float weight = 1.0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + const auto mcpJetsPerMcCollision = mcpjets.sliceBy(JetMCPPerMcCollision, collision.mcCollisionId()); + + for (auto mcpjet : mcpJetsPerMcCollision) { + if (mcpjet.pt() > pTHatMaxMCP * pTHat) { // outlier rejection for MCP + return; + } + } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content @@ -807,12 +815,12 @@ struct FullJetSpectrapp { } for (const auto& mcdjet : mcdjets) { - if (mcdjet.pt() > pTHatMaxMCD * pTHat) { - eventAccepted = false; ////reject the whole event for outlier jets + // Check if MCD jet is within the EMCAL fiducial region + if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { fakemcdjet++; registry.fill(HIST("h_collisions_weighted"), 8.0); // Fake Matched Weighted MCD Jets registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakemcdjet, eventWeight); - break; + continue; } if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; @@ -820,31 +828,20 @@ struct FullJetSpectrapp { if (!isAcceptedJet(mcdjet)) { continue; } - if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { - continue; - } - if (!mcdjet.has_matchedJetGeo()) { - continue; - } for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - if (mcpjet.pt() > pTHatMaxMCP * pTHat) { - eventAccepted = false; // reject the whole event for outlier jets + // apply emcal fiducial cuts to the matched particle level jets + if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { fakemcpjet++; registry.fill(HIST("h_collisions_weighted"), 9.0); // Fake Matched Weighted MCP Jets registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakemcpjet, eventWeight); - break; - } - if (!mcpjet.has_matchedJetGeo()) { - continue; - } - // apply emcal fiducial cuts to the matched particle level jets - if (mcpjet.eta() > jetEtaMax || mcpjet.phi() > jetPhiMax || !jetfindingutilities::isInEtaAcceptance(mcpjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; } + // If both MCD-MCP matched jet pairs are within the EMCAL fiducial region, fill these histos registry.fill(HIST("h_full_matchedmcpjet_eta"), mcpjet.eta(), eventWeight); registry.fill(HIST("h_full_matchedmcpjet_phi"), mcpjet.phi(), eventWeight); - fillMatchedHistograms(mcdjet, mcdjet.eventWeight()); + fillMatchedHistograms(mcdjet, eventWeight); } // mcpjet + // Fill MCD jet histograms if a valid MCP jet match was found within the EMCAL region registry.fill(HIST("h_full_matchedmcdjet_eta"), mcdjet.eta(), eventWeight); registry.fill(HIST("h_full_matchedmcdjet_phi"), mcdjet.phi(), eventWeight); } // mcdjet diff --git a/PWGJE/Tasks/gammajettreeproducer.cxx b/PWGJE/Tasks/gammajettreeproducer.cxx new file mode 100644 index 00000000000..d721ca725df --- /dev/null +++ b/PWGJE/Tasks/gammajettreeproducer.cxx @@ -0,0 +1,295 @@ +// 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 "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/GammaJetAnalysisTree.h" + +#include "EMCALBase/Geometry.h" +#include "EMCALCalib/BadChannelMap.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "DataFormatsEMCAL/Cell.h" +#include "DataFormatsEMCAL/Constants.h" +#include "DataFormatsEMCAL/AnalysisCluster.h" +#include "TVector2.h" + +#include "CommonDataFormat/InteractionRecord.h" + +#include "EventFiltering/filterTables.h" + +// \struct GammaJetTreeProducer +/// \brief Task to produce a tree for gamma-jet analysis, including photons (and information of isolation) and charged and full jets +/// \author Florian Jonas , UC Berkeley/LBNL +/// \since 02.08.2024 +/// +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using selectedClusters = o2::soa::Filtered; + +#include "Framework/runDataProcessing.h" + +struct GammaJetTreeProducer { + // analysis tree + // charged jets + // photon candidates + Produces chargedJetsTable; + Produces eventsTable; + Produces gammasTable; + + HistogramRegistry mHistograms{"GammaJetTreeProducerHisto"}; + + // --------------- + // Configureables + // --------------- + + // event cuts + Configurable mVertexCut{"vertexCut", 10.0, "apply z-vertex cut with value in cm"}; + Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; + 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 + trackSelections{"trackSelections", "globalTracks", "set track selections"}; + Configurable trackMinPt{"trackMinPt", 0.15, "minimum track pT cut"}; + Configurable jetPtMin{"jetPtMin", 5.0, "minimum jet pT cut"}; + Configurable jetR{"jetR", 0.4, "jet resolution parameter"}; + Configurable isoR{"isoR", 0.4, "isolation cone radius"}; + + // cluster cuts + Configurable mClusterDefinition{"clusterDefinition", 10, "cluster definition to be selected, e.g. 10=kV3Default"}; + // Preslice perClusterMatchedTracks = o2::aod::jcluster::clusterId; + + int mRunNumber = 0; + int eventSelection = -1; + int trackSelection = -1; + + std::unordered_map collisionMapping; + std::vector triggerMaskBits; + + void init(InitContext const&) + { + using o2HistType = HistType; + using o2Axis = AxisSpec; + + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); + triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); + + // create histograms + LOG(info) << "Creating histograms"; + + const o2Axis ptAxis{100, 0, 100, "p_{T} (GeV/c)"}; + const o2Axis energyAxis{100, 0, 100, "E (GeV)"}; + const o2Axis m02Axis{100, 0, 3, "m02"}; + + mHistograms.add("clusterE", "Energy of cluster", o2HistType::kTH1F, {energyAxis}); + mHistograms.add("trackPt", "pT of track", o2HistType::kTH1F, {ptAxis}); + mHistograms.add("chjetPt", "pT of charged jet", o2HistType::kTH1F, {ptAxis}); + mHistograms.add("chjetpt_vs_constpt", "pT of charged jet vs pT of constituents", o2HistType::kTH2F, {ptAxis, ptAxis}); + } + + // --------------------- + // Helper functions + // --------------------- + bool isTrackSelected(const auto& track) + { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + return false; + } + if (track.pt() < trackMinPt) { + return false; + } + + return true; + } + + bool isEventAccepted(const auto& collision) + { + + if (collision.posZ() > mVertexCut) { + return false; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { + return false; + } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return false; + } + if (!jetderiveddatautilities::eventEMCAL(collision)) { + return false; + } + return true; + } + + double ch_iso_in_cone(const auto& cluster, JetTracks const& tracks, float radius = 0.4) + { + double iso = 0; + for (auto track : tracks) { + if (!isTrackSelected(track)) { + continue; + } + // make dR function live somwhere else + float dR = jetutilities::deltaR(cluster, track); + if (dR < radius) { + iso += track.pt(); + } + } + return iso; + } + double ch_perp_cone_rho(const auto& cluster, JetTracks const& tracks, float radius = 0.4) + { + double ptSumLeft = 0; + double ptSumRight = 0; + + double cPhi = TVector2::Phi_0_2pi(cluster.phi()); + + // rotate cone left by 90 degrees + float cPhiLeft = cPhi - TMath::Pi() / 2; + float cPhiRight = cPhi + TMath::Pi() / 2; + + // loop over tracks + float dRLeft, dRRight; + for (auto track : tracks) { + if (!isTrackSelected(track)) { + continue; + } + dRLeft = jetutilities::deltaR(cluster.eta(), cPhiLeft, track.eta(), track.phi()); + dRRight = jetutilities::deltaR(cluster.eta(), cPhiRight, track.eta(), track.phi()); + + if (dRLeft < radius) { + ptSumLeft += track.pt(); + } + if (dRRight < radius) { + ptSumRight += track.pt(); + } + } + + float rho = (ptSumLeft + ptSumRight) / (2 * TMath::Pi() * radius * radius); + return rho; + } + + // --------------------- + // Processing functions + // --------------------- + void processClearMaps(JetCollisions const&) + { + collisionMapping.clear(); + } + PROCESS_SWITCH(GammaJetTreeProducer, processClearMaps, "process function that clears all the maps in each dataframe", true); + + // define cluster filter. It selects only those clusters which are of the type + // sadly passing of the string at runtime is not possible for technical region so cluster definition is + // an integer instead + Filter clusterDefinitionSelection = (o2::aod::jcluster::definition == mClusterDefinition); + // Process clusters + void processClusters(soa::Join::iterator const& collision, selectedClusters const& clusters, JetTracks const& tracks) + { + if (!isEventAccepted(collision)) { + return; + } + + eventsTable(collision.multiplicity(), collision.centrality(), collision.rho(), collision.eventSel(), collision.alias_raw()); + collisionMapping[collision.globalIndex()] = eventsTable.lastIndex(); + + // loop over clusters + for (auto cluster : clusters) { + + // fill histograms + mHistograms.fill(HIST("clusterE"), cluster.energy()); + + double isoraw = ch_iso_in_cone(cluster, tracks, isoR); + double perpconerho = ch_perp_cone_rho(cluster, tracks, isoR); + + // find closest matched track + double dEta = 0; + double dPhi = 0; + // double dRMin = 100; + double p = -1; + + // auto tracksofcluster = matchedtracks.sliceBy(perClusterMatchedTracks, cluster.globalIndex()); + // for (const auto& match : tracksofcluster) { + // // ask the jtracks table for track with ID trackID + // double dR = deltaR(cluster.eta(), cluster.phi(), match.tracks_as().Eta(), match.tracks_as().Phi()); + // if (dR < dRMin) { + // dRMin = dR; + // dEta = cluster.eta() - match.tracks_as().eta(); + // dPhi = TVector2::Phi_0_2pi(cluster.phi()) - TVector2::Phi_0_2pi(match.tracks_as().phi()); + // if (abs(dPhi) > M_PI) { + // dPhi = 2 * M_PI - abs(dPhi); + // } + // p = match.tracks_as().p(); + // } + // } + + // // for compression reasons make dPhi and dEta 0 if no match is found + // if (p == -1) { + // dPhi = 0; + // dEta = 0; + // } + + gammasTable(eventsTable.lastIndex(), cluster.energy(), cluster.eta(), cluster.phi(), cluster.m02(), cluster.m20(), cluster.nCells(), cluster.time(), cluster.isExotic(), cluster.distanceToBadChannel(), cluster.nlm(), isoraw, perpconerho, dPhi, dEta, p); + } + + // dummy loop over tracks + for (auto track : tracks) { + mHistograms.fill(HIST("trackPt"), track.pt()); + } + } + PROCESS_SWITCH(GammaJetTreeProducer, processClusters, "Process EMCal clusters", true); + + Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f); + // Process charged jets + void processChargedJets(soa::Join::iterator const& collision, soa::Filtered> const& chargedJets, JetTracks const&) + { + // event selection + if (!isEventAccepted(collision)) { + return; + } + + // loop over charged jets + for (auto jet : chargedJets) { + if (jet.pt() < jetPtMin) + continue; + ushort nconst = 0; + // loop over constituents + for (auto& constituent : jet.template tracks_as()) { + mHistograms.fill(HIST("chjetpt_vs_constpt"), jet.pt(), constituent.pt()); + nconst++; + } + int32_t storedColIndex = -1; + if (auto foundCol = collisionMapping.find(collision.globalIndex()); foundCol != collisionMapping.end()) { + storedColIndex = foundCol->second; + } + chargedJetsTable(storedColIndex, jet.pt(), jet.eta(), jet.phi(), jet.energy(), jet.mass(), jet.area(), nconst); + // fill histograms + mHistograms.fill(HIST("chjetPt"), jet.pt()); + } + } + PROCESS_SWITCH(GammaJetTreeProducer, processChargedJets, "Process charged jets", true); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc, TaskName{"gamma-jet-tree-producer"})}; + return workflow; +} diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index 63b97424224..fa6c54bae5e 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -69,10 +69,11 @@ struct hJetAnalysis { 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 eventCuts = nabs(aod::jcollision::posZ) < vertexZCut; + Filter eventTrackLevelCuts = nabs(aod::jcollision::posZ) < vertexZCut; HistogramRegistry registry{"registry", {{"hNtrig", "number of triggers;trigger type;entries", {HistType::kTH1F, {{2, 0, 2}}}}, + {"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, {{160, -1.0, 7.0}}}}, @@ -123,6 +124,8 @@ struct hJetAnalysis { int eventSelection = -1; int trackSelection = -1; + Service pdg; + void init(InitContext const&) { eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); @@ -130,7 +133,7 @@ struct hJetAnalysis { 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 eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut); + Filter eventTrackLevelCuts = nabs(aod::jcollision::posZ) < vertexZCut; } template @@ -268,6 +271,13 @@ struct hJetAnalysis { is_sig_col = false; for (auto& particle : particles) { + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (!pdgParticle) { + continue; + } + if ((pdgParticle->Charge() == 0.0) || (!particle.isPhysicalPrimary())) { + continue; + } if (is_sig_col && particle.pt() < pt_TTsig_max && particle.pt() > pt_TTsig_min) { phi_TT_ar.push_back(particle.phi()); n_TT++; @@ -420,6 +430,7 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); fillHistograms(jets, jetsWTA, tracks); } PROCESS_SWITCH(hJetAnalysis, processData, "process data", true); @@ -432,11 +443,12 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); fillHistograms(jets, jetsWTA, tracks); } PROCESS_SWITCH(hJetAnalysis, processMCD, "process MC detector level", false); - void processMCDWeighted(soa::Join::iterator const& collision, + void processMCDWeighted(soa::Filtered>::iterator const& collision, soa::Filtered> const& jets, soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) @@ -444,25 +456,34 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ(), collision.mcCollision().weight()); fillHistograms(jets, jetsWTA, tracks, collision.mcCollision().weight()); } PROCESS_SWITCH(hJetAnalysis, processMCDWeighted, "process MC detector level with event weights", false); - void processMCP(JetMcCollision const& /*collision*/, + void processMCP(JetMcCollision const& collision, soa::Filtered> const& jets, soa::Filtered> const& jetsWTA, JetParticles const& particles) { + if (std::abs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); fillMCPHistograms(jets, jetsWTA, particles); } PROCESS_SWITCH(hJetAnalysis, processMCP, "process MC particle level", false); - void processMCPWeighted(soa::Join::iterator const& collision, + void processMCPWeighted(JetMcCollision const& collision, soa::Filtered> const& jets, soa::Filtered> const& jetsWTA, JetParticles const& particles) { - fillMCPHistograms(jets, jetsWTA, particles, collision.mcCollision().weight()); + if (std::abs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hZvtxSelected"), collision.posZ(), collision.weight()); + fillMCPHistograms(jets, jetsWTA, particles, collision.weight()); } PROCESS_SWITCH(hJetAnalysis, processMCPWeighted, "process MC particle level with event weights", false); @@ -478,6 +499,7 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); for (const auto& mcdjet : mcdjets) { fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets); @@ -497,6 +519,7 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); for (const auto& mcdjet : mcdjets) { fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, mcdjet.eventWeight()); @@ -516,6 +539,7 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); bool ishJetEvent = false; for (auto& track : tracks) { @@ -544,6 +568,7 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); bool ishJetEvent = false; for (auto& track : tracks) { diff --git a/PWGJE/Tasks/jetfinderQA.cxx b/PWGJE/Tasks/jetfinderQA.cxx index bbf588cee17..edd974c71ed 100644 --- a/PWGJE/Tasks/jetfinderQA.cxx +++ b/PWGJE/Tasks/jetfinderQA.cxx @@ -66,7 +66,9 @@ struct JetFinderQATask { Configurable nBinsEta{"nBinsEta", 200, "number of bins for eta axes"}; Configurable jetAreaFractionMin{"jetAreaFractionMin", -99.0, "used to make a cut on the jet areas"}; Configurable leadingConstituentPtMin{"leadingConstituentPtMin", -99.0, "minimum pT selection on jet constituent"}; + Configurable leadingConstituentPtMax{"leadingConstituentPtMax", 9999.0, "maximum pT selection on jet constituent"}; Configurable randomConeR{"randomConeR", 0.4, "size of random Cone for estimating background fluctuations"}; + Configurable randomConeLeadJetDeltaR{"randomConeLeadJetDeltaR", -99.0, "min distance between leading jet axis and random cone (RC) axis; if negative, min distance is set to automatic value of R_leadJet+R_RC "}; Configurable checkMcCollisionIsMatched{"checkMcCollisionIsMatched", false, "0: count whole MCcollisions, 1: select MCcollisions which only have their correspond collisions"}; Configurable trackOccupancyInTimeRangeMax{"trackOccupancyInTimeRangeMax", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range; only applied to reconstructed collisions (data and mcd jets), not mc collisions (mcp jets)"}; Configurable trackOccupancyInTimeRangeMin{"trackOccupancyInTimeRangeMin", -999999, "minimum occupancy of tracks in neighbouring collisions in a given time range; only applied to reconstructed collisions (data and mcd jets), not mc collisions (mcp jets)"}; @@ -207,6 +209,7 @@ struct JetFinderQATask { if (doprocessRandomConeData || doprocessRandomConeMCD) { registry.add("h2_centrality_rhorandomcone", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTH2F, {{1100, 0., 110.}, {800, -400.0, 400.0}}}); + registry.add("h2_centrality_rhorandomconerandomtrackdirection", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTH2F, {{1100, 0., 110.}, {800, -400.0, 400.0}}}); registry.add("h2_centrality_rhorandomconewithoutleadingjet", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTH2F, {{1100, 0., 110.}, {800, -400.0, 400.0}}}); } @@ -333,18 +336,30 @@ struct JetFinderQATask { return false; } } - if (leadingConstituentPtMin > -98.0) { - bool isMinleadingConstituent = false; - for (auto& constituent : jet.template tracks_as()) { - if (constituent.pt() >= leadingConstituentPtMin) { - isMinleadingConstituent = true; - break; + bool checkConstituentPt = true; + bool checkConstituentMinPt = (leadingConstituentPtMin > -98.0); + bool checkConstituentMaxPt = (leadingConstituentPtMax < 9998.0); + if (!checkConstituentMinPt && !checkConstituentMaxPt) { + checkConstituentPt = false; + } + + if (checkConstituentPt) { + bool isMinLeadingConstituent = !checkConstituentMinPt; + bool isMaxLeadingConstituent = true; + + for (const auto& constituent : jet.template tracks_as()) { + double pt = constituent.pt(); + + if (checkConstituentMinPt && pt >= leadingConstituentPtMin) { + isMinLeadingConstituent = true; + } + if (checkConstituentMaxPt && pt > leadingConstituentPtMax) { + isMaxLeadingConstituent = false; } } - if (!isMinleadingConstituent) { - return false; - } + return isMinLeadingConstituent && isMaxLeadingConstituent; } + return true; } @@ -592,13 +607,26 @@ struct JetFinderQATask { } registry.fill(HIST("h2_centrality_rhorandomcone"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * collision.rho()); + // randomised eta,phi for tracks, to assess part of fluctuations coming from statistically independently emitted particles + randomConePt = 0; + for (auto const& track : tracks) { + if (jetderiveddatautilities::selectTrack(track, trackSelection)) { + float dPhi = RecoDecay::constrainAngle(randomNumber.Uniform(0.0, 2 * M_PI) - randomConePhi, static_cast(-M_PI)); // ignores actual phi of track + float dEta = randomNumber.Uniform(trackEtaMin, trackEtaMax) - randomConeEta; // ignores actual eta of track + if (TMath::Sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { + randomConePt += track.pt(); + } + } + } + registry.fill(HIST("h2_centrality_rhorandomconerandomtrackdirection"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * collision.rho()); + // 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(-M_PI)); float dEtaLeadingJet = jets.iteratorAt(0).eta() - randomConeEta; bool jetWasInCone = false; - while (TMath::Sqrt(dEtaLeadingJet * dEtaLeadingJet + dPhiLeadingJet * dPhiLeadingJet) < jets.iteratorAt(0).r() / 100.0 + randomConeR) { + while ((randomConeLeadJetDeltaR <= 0 && (TMath::Sqrt(dEtaLeadingJet * dEtaLeadingJet + dPhiLeadingJet * dPhiLeadingJet) < jets.iteratorAt(0).r() / 100.0 + randomConeR)) || (randomConeLeadJetDeltaR > 0 && (TMath::Sqrt(dEtaLeadingJet * dEtaLeadingJet + dPhiLeadingJet * dPhiLeadingJet) < randomConeLeadJetDeltaR))) { jetWasInCone = true; randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); randomConePhi = randomNumber.Uniform(0.0, 2 * M_PI); diff --git a/PWGJE/Tasks/jetfinderhfQA.cxx b/PWGJE/Tasks/jetfinderhfQA.cxx index 9ec68be39a8..13a185ce36b 100644 --- a/PWGJE/Tasks/jetfinderhfQA.cxx +++ b/PWGJE/Tasks/jetfinderhfQA.cxx @@ -492,11 +492,6 @@ struct JetFinderHFQATask { PresliceOptional> perBplusCandidateTracks = aod::bkgbplus::candidateId; PresliceOptional> perDielectronCandidateTracks = aod::bkgdielectron::candidateId; - PresliceOptional perD0CandidateRhos = aod::bkgd0::candidateId; - PresliceOptional perLcCandidateRhos = aod::bkglc::candidateId; - PresliceOptional perBplusCandidateRhos = aod::bkgbplus::candidateId; - PresliceOptional perDielectronCandidateRhos = aod::bkgdielectron::candidateId; - template bool isAcceptedJet(V const& jet) { @@ -945,15 +940,14 @@ struct JetFinderHFQATask { } } - template - void randomCone(T const& collision, U const& jets, V const& candidates, M const& bkgRhos, N const& tracks) + template + void randomCone(T const& collision, U const& jets, V const& candidates, M const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } for (auto const& candidate : candidates) { - auto bkgRho = jetcandidateutilities::slicedPerCandidate(bkgRhos, candidate, perD0CandidateRhos, perLcCandidateRhos, perBplusCandidateRhos, perDielectronCandidateRhos).iteratorAt(0); TRandom3 randomNumber(0); float randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); float randomConePhi = randomNumber.Uniform(0.0, 2 * M_PI); @@ -967,7 +961,7 @@ struct JetFinderHFQATask { } } } - registry.fill(HIST("h2_centrality_rhorandomcone"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * bkgRho.rho()); + registry.fill(HIST("h2_centrality_rhorandomcone"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * candidate.rho()); // 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 @@ -995,7 +989,7 @@ struct JetFinderHFQATask { } } } - registry.fill(HIST("h2_centrality_rhorandomconewithoutleadingjet"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * bkgRho.rho()); + registry.fill(HIST("h2_centrality_rhorandomconewithoutleadingjet"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * candidate.rho()); break; // currently only fills it for the first candidate in the event (not pT ordered). Jet is pT ordered so results for excluding leading jet might not be as expected } } @@ -1020,9 +1014,8 @@ struct JetFinderHFQATask { PROCESS_SWITCH(JetFinderHFQATask, processJetsData, "jet finder HF QA data", false); void processJetsRhoAreaSubData(soa::Filtered::iterator const& collision, - BkgRhoTable const& bkgRhos, JetTableDataJoined const& jets, - CandidateTableData const&, + soa::Join const&, JetTracks const&) { for (auto const& jet : jets) { @@ -1032,17 +1025,15 @@ struct JetFinderHFQATask { if (!isAcceptedJet(jet)) { continue; } - auto const jetCandidate = jet.template candidates_first_as(); - auto bkgRho = jetcandidateutilities::slicedPerCandidate(bkgRhos, jetCandidate, perD0CandidateRhos, perLcCandidateRhos, perBplusCandidateRhos, perDielectronCandidateRhos).iteratorAt(0); - fillRhoAreaSubtractedHistograms(jet, collision.centrality(), bkgRho.rho()); + auto const candidate = jet.template candidates_first_as>(); + fillRhoAreaSubtractedHistograms(jet, collision.centrality(), candidate.rho()); } } PROCESS_SWITCH(JetFinderHFQATask, processJetsRhoAreaSubData, "jet finder HF QA for rho-area subtracted jets", false); void processJetsRhoAreaSubMCD(soa::Filtered::iterator const& collision, - BkgRhoTable const& bkgRhos, JetTableMCDJoined const& jets, - CandidateTableMCD const&, + soa::Join const&, JetTracks const&) { for (auto const& jet : jets) { @@ -1052,9 +1043,8 @@ struct JetFinderHFQATask { if (!isAcceptedJet(jet)) { continue; } - auto const jetCandidate = jet.template candidates_first_as(); - auto bkgRho = jetcandidateutilities::slicedPerCandidate(bkgRhos, jetCandidate, perD0CandidateRhos, perLcCandidateRhos, perBplusCandidateRhos, perDielectronCandidateRhos).iteratorAt(0); - fillRhoAreaSubtractedHistograms(jet, collision.centrality(), bkgRho.rho()); + auto const candidate = jet.template candidates_first_as>(); + fillRhoAreaSubtractedHistograms(jet, collision.centrality(), candidate.rho()); } } PROCESS_SWITCH(JetFinderHFQATask, processJetsRhoAreaSubMCD, "jet finder HF QA for rho-area subtracted mcd jets", false); @@ -1520,13 +1510,12 @@ struct JetFinderHFQATask { } PROCESS_SWITCH(JetFinderHFQATask, processTracksSub, "QA for charged event-wise embedded subtracted tracks", false); - void processRho(JetCollision const& collision, CandidateTableData const& candidates, BkgRhoTable const& bkgRhos, soa::Filtered const& tracks) + void processRho(JetCollision const& collision, soa::Join const& candidates, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } for (auto const& candidate : candidates) { - auto bkgRho = jetcandidateutilities::slicedPerCandidate(bkgRhos, candidate, perD0CandidateRhos, perLcCandidateRhos, perBplusCandidateRhos, perDielectronCandidateRhos).iteratorAt(0); int nTracks = 0; for (auto const& track : tracks) { if (jetderiveddatautilities::selectTrack(track, trackSelection)) { @@ -1534,24 +1523,24 @@ struct JetFinderHFQATask { } } registry.fill(HIST("h2_centrality_ntracks"), collision.centrality(), nTracks); - registry.fill(HIST("h2_ntracks_rho"), nTracks, bkgRho.rho()); - registry.fill(HIST("h2_ntracks_rhom"), nTracks, bkgRho.rhoM()); - registry.fill(HIST("h2_centrality_rho"), collision.centrality(), bkgRho.rho()); - registry.fill(HIST("h2_centrality_rhom"), collision.centrality(), bkgRho.rhoM()); + registry.fill(HIST("h2_ntracks_rho"), nTracks, candidate.rho()); + registry.fill(HIST("h2_ntracks_rhom"), nTracks, candidate.rhoM()); + registry.fill(HIST("h2_centrality_rho"), collision.centrality(), candidate.rho()); + registry.fill(HIST("h2_centrality_rhom"), collision.centrality(), candidate.rhoM()); break; // currently only fills it for the first candidate in the event (not pT ordered) } } PROCESS_SWITCH(JetFinderHFQATask, processRho, "QA for rho-area subtracted jets", false); - void processRandomConeData(soa::Filtered::iterator const& collision, JetTableDataJoined const& jets, CandidateTableData const& candidates, BkgRhoTable const& bkgRhos, soa::Filtered const& tracks) + void processRandomConeData(soa::Filtered::iterator const& collision, JetTableDataJoined const& jets, soa::Join const& candidates, soa::Filtered const& tracks) { - randomCone(collision, jets, candidates, bkgRhos, tracks); + randomCone(collision, jets, candidates, tracks); } PROCESS_SWITCH(JetFinderHFQATask, processRandomConeData, "QA for random cone estimation of background fluctuations in data", false); - void processRandomConeMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, CandidateTableMCD const& candidates, BkgRhoTable const& bkgRhos, soa::Filtered const& tracks) + void processRandomConeMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, soa::Join const& candidates, soa::Filtered const& tracks) { - randomCone(collision, jets, candidates, bkgRhos, tracks); + randomCone(collision, jets, candidates, tracks); } PROCESS_SWITCH(JetFinderHFQATask, processRandomConeMCD, "QA for random cone estimation of background fluctuations in mcd", false); diff --git a/PWGJE/Tasks/jettaggerhfQA.cxx b/PWGJE/Tasks/jettaggerhfQA.cxx index 9f7fa7d30ae..9bbe0f41cef 100644 --- a/PWGJE/Tasks/jettaggerhfQA.cxx +++ b/PWGJE/Tasks/jettaggerhfQA.cxx @@ -36,7 +36,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -template +template struct JetTaggerHFQA { // task on/off configuration @@ -313,6 +313,9 @@ struct JetTaggerHFQA { registry.add("h3_jet_pt_2prong_Sxy_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyAxis}, {jetFlavourAxis}}}); registry.add("h3_jet_pt_2prong_Sxyz_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyzAxis}, {jetFlavourAxis}}}); registry.add("h3_jet_pt_2prong_mass_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {massAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_2prong_Sxy_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_2prong_Sxyz_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyzAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_2prong_mass_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {massAxis}, {jetFlavourAxis}}}); } if (doprocessSV3ProngMCD || doprocessSV3ProngMCDWeighted) { registry.add("h2_3prong_nprongs_flavour", "", {HistType::kTH2F, {{nprongsAxis}, {jetFlavourAxis}}}); @@ -325,6 +328,9 @@ struct JetTaggerHFQA { registry.add("h3_jet_pt_3prong_Sxy_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyAxis}, {jetFlavourAxis}}}); registry.add("h3_jet_pt_3prong_Sxyz_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyzAxis}, {jetFlavourAxis}}}); registry.add("h3_jet_pt_3prong_mass_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {massAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_3prong_Sxy_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_3prong_Sxyz_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {SxyzAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_3prong_mass_N1_flavour", "", {HistType::kTH3F, {{jetPtAxis}, {massAxis}, {jetFlavourAxis}}}); } if (doprocessSV2ProngMCPMCDMatched || doprocessSV2ProngMCPMCDMatchedWeighted) { registry.add("h3_jet_pt_2prong_Lxy_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {LxyAxis}, {jetFlavourAxis}}}); @@ -347,6 +353,9 @@ struct JetTaggerHFQA { registry.add("h3_jet_pt_3prong_Sxy_N1_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {SxyAxis}, {jetFlavourAxis}}}); registry.add("h3_jet_pt_3prong_Sxyz_N1_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {SxyzAxis}, {jetFlavourAxis}}}); registry.add("h3_jet_pt_3prong_mass_N1_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {massAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_3prong_Sxy_N1_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {SxyAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_3prong_Sxyz_N1_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {SxyzAxis}, {jetFlavourAxis}}}); + registry.add("h3_taggedjet_pt_3prong_mass_N1_flavour_run2", "", {HistType::kTH3F, {{jetPtAxis}, {massAxis}, {jetFlavourAxis}}}); } } @@ -357,8 +366,6 @@ struct JetTaggerHFQA { using JetTagTracksData = soa::Join; using JetTagTracksMCD = soa::Join; - using JetTagTableMCDMCPMatched = soa::Join; - using JetTagTableMCPMCDMatched = soa::Join; std::function&, const std::vector&)> sortImp = [](const std::vector& a, const std::vector& b) { @@ -857,6 +864,11 @@ struct JetTaggerHFQA { registry.fill(HIST("h3_jet_pt_2prong_Sxy_N1_flavour"), mcdjet.pt(), maxSxy, origin, eventWeight); registry.fill(HIST("h3_jet_pt_2prong_Sxyz_N1_flavour"), mcdjet.pt(), maxSxyz, origin, eventWeight); registry.fill(HIST("h3_jet_pt_2prong_mass_N1_flavour"), mcdjet.pt(), massSV, origin, eventWeight); + if (!mcdjet.flagtaggedjetSV()) + return; + registry.fill(HIST("h3_taggedjet_pt_2prong_Sxy_N1_flavour"), mcdjet.pt(), maxSxy, origin, eventWeight); + registry.fill(HIST("h3_taggedjet_pt_2prong_Sxyz_N1_flavour"), mcdjet.pt(), maxSxyz, origin, eventWeight); + registry.fill(HIST("h3_taggedjet_pt_2prong_mass_N1_flavour"), mcdjet.pt(), massSV, origin, eventWeight); } template @@ -927,6 +939,11 @@ struct JetTaggerHFQA { registry.fill(HIST("h3_jet_pt_3prong_Sxy_N1_flavour"), mcdjet.pt(), maxSxy, origin, eventWeight); registry.fill(HIST("h3_jet_pt_3prong_Sxyz_N1_flavour"), mcdjet.pt(), maxSxyz, origin, eventWeight); registry.fill(HIST("h3_jet_pt_3prong_mass_N1_flavour"), mcdjet.pt(), massSV, origin, eventWeight); + if (!mcdjet.flagtaggedjetSV()) + return; + registry.fill(HIST("h3_taggedjet_pt_3prong_Sxy_N1_flavour"), mcdjet.pt(), maxSxy, origin, eventWeight); + registry.fill(HIST("h3_taggedjet_pt_3prong_Sxyz_N1_flavour"), mcdjet.pt(), maxSxyz, origin, eventWeight); + registry.fill(HIST("h3_taggedjet_pt_3prong_mass_N1_flavour"), mcdjet.pt(), massSV, origin, eventWeight); } template @@ -964,6 +981,11 @@ struct JetTaggerHFQA { registry.fill(HIST("h3_jet_pt_3prong_Sxy_N1_flavour_run2"), mcdjet.pt(), maxSxy, jetflavourRun2Def, eventWeight); registry.fill(HIST("h3_jet_pt_3prong_Sxyz_N1_flavour_run2"), mcdjet.pt(), maxSxyz, jetflavourRun2Def, eventWeight); registry.fill(HIST("h3_jet_pt_3prong_mass_N1_flavour_run2"), mcdjet.pt(), massSV, jetflavourRun2Def, eventWeight); + if (!mcdjet.flagtaggedjetSV()) + return; + registry.fill(HIST("h3_taggedjet_pt_3prong_Sxy_N1_flavour_run2"), mcdjet.pt(), maxSxy, jetflavourRun2Def, eventWeight); + registry.fill(HIST("h3_taggedjet_pt_3prong_Sxyz_N1_flavour_run2"), mcdjet.pt(), maxSxyz, jetflavourRun2Def, eventWeight); + registry.fill(HIST("h3_taggedjet_pt_3prong_mass_N1_flavour_run2"), mcdjet.pt(), massSV, jetflavourRun2Def, eventWeight); } void processDummy(aod::Collision const&, aod::Tracks const&) @@ -998,7 +1020,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processTracksDca, "Fill inclusive tracks' imformation for data", false); - void processIPsData(soa::Filtered::iterator const& collision, JetTagTableData const& jets, JetTagTracksData const& jtracks) + void processIPsData(soa::Filtered::iterator const& collision, soa::Join const& jets, JetTagTracksData const& jtracks) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1015,7 +1037,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processIPsData, "Fill impact parameter imformation for data jets", false); - void processIPsMCD(soa::Filtered::iterator const& collision, JetTagTableMCD const& mcdjets, JetTagTracksMCD const& jtracks, JetParticles&) + void processIPsMCD(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, JetTagTracksMCD const& jtracks, JetParticles&) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1032,7 +1054,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processIPsMCD, "Fill impact parameter imformation for mcd jets", false); - void processIPsMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, JetTagTracksMCD const& jtracks, JetParticles&) + void processIPsMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, JetTagTracksMCD const& jtracks, JetParticles&) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1046,7 +1068,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processIPsMCDWeighted, "Fill impact parameter imformation for mcd jets", false); - void processIPsMCP(soa::Filtered const& collisions, JetTagTableMCP const& mcpjets, JetParticles&) + void processIPsMCP(soa::Join const& mcpjets, JetParticles&, JetMcCollisions const&, soa::Filtered const& collisions) { for (auto mcpjet : mcpjets) { if (!jetfindingutilities::isInEtaAcceptance(mcpjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -1059,15 +1081,15 @@ struct JetTaggerHFQA { auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, mcpjet.mcCollisionId()); if (collisionspermcpjet.size() >= 1 && jetderiveddatautilities::selectCollision(collisionspermcpjet.begin(), eventSelection)) { fillHistogramIPsMCP(mcpjet); - } else { - fillHistogramIPsMCP(mcpjet); } + } else { + fillHistogramIPsMCP(mcpjet); } } } PROCESS_SWITCH(JetTaggerHFQA, processIPsMCP, "Fill impact parameter imformation for mcp jets", false); - void processIPsMCPWeighted(soa::Filtered const& collisions, soa::Join const& mcpjets, JetParticles&) + void processIPsMCPWeighted(soa::Filtered const& collisions, soa::Join const& mcpjets, JetParticles&) { for (auto mcpjet : mcpjets) { if (!jetfindingutilities::isInEtaAcceptance(mcpjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -1088,7 +1110,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processIPsMCPWeighted, "Fill impact parameter imformation for mcp jets weighted", false); - void processIPsMCPMCDMatched(soa::Filtered>::iterator const& collision, JetTagTableMCDMCPMatched const& mcdjets, JetTagTableMCPMCDMatched const& mcpjets, JetTagTracksMCD const& jtracks, JetParticles& particles) + void processIPsMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, JetTagTracksMCD const& jtracks, JetParticles& particles) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1106,7 +1128,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processIPsMCPMCDMatched, "Fill impact parameter imformation for mcp mcd matched jets", false); - void processIPsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, JetTagTracksMCD const& jtracks, JetParticles& particles) + void processIPsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, JetTagTracksMCD const& jtracks, JetParticles& particles) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1124,7 +1146,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processIPsMCPMCDMatchedWeighted, "Fill impact parameter imformation for mcp mcd matched jets", false); - void processJPData(soa::Filtered::iterator const& collision, JetTagTableData const& jets, JetTagTracksData const&) + void processJPData(soa::Filtered::iterator const& collision, soa::Join const& jets, JetTagTracksData const&) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1141,7 +1163,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processJPData, "Fill jet probability imformation for data jets", false); - void processJPMCD(soa::Filtered::iterator const& collision, JetTagTableMCD const& mcdjets, JetTagTracksMCD const&) + void processJPMCD(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, JetTagTracksMCD const&) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1158,7 +1180,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processJPMCD, "Fill jet probability imformation for mcd jets", false); - void processJPMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, JetTagTracksMCD const&) + void processJPMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, JetTagTracksMCD const&) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1175,7 +1197,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processJPMCDWeighted, "Fill jet probability imformation for mcd jets", false); - void processSV2ProngData(soa::Filtered::iterator const& collision, soa::Join const& jets, aod::DataSecondaryVertex2Prongs const& prongs) + void processSV2ProngData(soa::Filtered::iterator const& collision, soa::Join const& jets, aod::DataSecondaryVertex2Prongs const& prongs) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1192,7 +1214,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV2ProngData, "Fill 2prong imformation for data jets", false); - void processSV3ProngData(soa::Filtered::iterator const& collision, soa::Join const& jets, aod::DataSecondaryVertex3Prongs const& prongs) + void processSV3ProngData(soa::Filtered::iterator const& collision, soa::Join const& jets, aod::DataSecondaryVertex3Prongs const& prongs) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1209,7 +1231,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV3ProngData, "Fill 2prong imformation for data jets", false); - void processSV2ProngMCD(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex2Prongs const& prongs) + void processSV2ProngMCD(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex2Prongs const& prongs) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1226,7 +1248,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV2ProngMCD, "Fill 2prong imformation for mcd jets", false); - void processSV2ProngMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex2Prongs const& prongs) + void processSV2ProngMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex2Prongs const& prongs) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1243,7 +1265,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV2ProngMCDWeighted, "Fill 2prong imformation for mcd jets", false); - void processSV2ProngMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, JetTagTableMCPMCDMatched const& mcpjets, aod::MCDSecondaryVertex2Prongs const& prongs, JetParticles& particles) + void processSV2ProngMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, aod::MCDSecondaryVertex2Prongs const& prongs, JetParticles& particles) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1261,7 +1283,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV2ProngMCPMCDMatched, "Fill 2prong imformation for mcd jets", false); - void processSV2ProngMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, JetTagTableMCPMCDMatched const& mcpjets, aod::MCDSecondaryVertex2Prongs const& prongs, JetParticles& particles) + void processSV2ProngMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, aod::MCDSecondaryVertex2Prongs const& prongs, JetParticles& particles) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1279,7 +1301,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV2ProngMCPMCDMatchedWeighted, "Fill 2prong imformation for mcd jets", false); - void processSV3ProngMCD(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex3Prongs const& prongs) + void processSV3ProngMCD(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex3Prongs const& prongs) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1296,7 +1318,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV3ProngMCD, "Fill 3prong imformation for mcd jets", false); - void processSV3ProngMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex3Prongs const& prongs) + void processSV3ProngMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, aod::MCDSecondaryVertex3Prongs const& prongs) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1313,7 +1335,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV3ProngMCDWeighted, "Fill 3prong imformation for mcd jets", false); - void processSV3ProngMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, JetTagTableMCPMCDMatched const& mcpjets, aod::MCDSecondaryVertex3Prongs const& prongs, JetParticles& particles) + void processSV3ProngMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, aod::MCDSecondaryVertex3Prongs const& prongs, JetParticles& particles) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1331,7 +1353,7 @@ struct JetTaggerHFQA { } PROCESS_SWITCH(JetTaggerHFQA, processSV3ProngMCPMCDMatched, "Fill 3prong imformation for mcd jets", false); - void processSV3ProngMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, JetTagTableMCPMCDMatched const& mcpjets, aod::MCDSecondaryVertex3Prongs const& prongs, JetParticles& particles) + void processSV3ProngMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, aod::MCDSecondaryVertex3Prongs const& prongs, JetParticles& particles) { if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; @@ -1350,13 +1372,11 @@ struct JetTaggerHFQA { PROCESS_SWITCH(JetTaggerHFQA, processSV3ProngMCPMCDMatchedWeighted, "Fill 3prong imformation for mcd jets", false); }; -using JetTaggerQAChargedDataJets = soa::Join; -using JetTaggerQAChargedMCDJets = soa::Join; -using JetTaggerQAChargedMCDMCPJets = soa::Join; -using JetTaggerQAChargedMCPJets = soa::Join; -using JetTaggerQAChargedMCPMCDJets = soa::Join; +using JetTaggerQAChargedDataJets = soa::Join; +using JetTaggerQAChargedMCDJets = soa::Join; +using JetTaggerQAChargedMCPJets = soa::Join; -using JetTaggerQACharged = JetTaggerHFQA; +using JetTaggerQACharged = JetTaggerHFQA; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/Tasks/statPromptPhoton.cxx b/PWGJE/Tasks/statPromptPhoton.cxx index 1b3d275ec37..31fc8570a26 100644 --- a/PWGJE/Tasks/statPromptPhoton.cxx +++ b/PWGJE/Tasks/statPromptPhoton.cxx @@ -136,6 +136,7 @@ struct statPromptPhoton { ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// template + double GetPtHadSum(const Tracks& tracks, const Trigger& trigger, double MinR, double MaxR, bool IsStern, bool IsParticle, bool DodR) { double eta_trigger, phi_trigger; diff --git a/PWGLF/DataModel/LFDoubleCascTables.h b/PWGLF/DataModel/LFDoubleCascTables.h new file mode 100644 index 00000000000..49e3b6604de --- /dev/null +++ b/PWGLF/DataModel/LFDoubleCascTables.h @@ -0,0 +1,73 @@ +// 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 "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" + +#ifndef PWGLF_DATAMODEL_LFDOUBLECASCTABLES_H_ +#define PWGLF_DATAMODEL_LFDOUBLECASCTABLES_H_ + +namespace o2::aod +{ + +namespace DoubleCascTables +{ +DECLARE_SOA_COLUMN(PtCasc1, ptCasc1, float); // signed pt of the cascade +DECLARE_SOA_COLUMN(EtaCasc1, etaCasc1, float); +DECLARE_SOA_COLUMN(PhiCasc1, phiCasc1, float); +DECLARE_SOA_COLUMN(CascDecLength1, cascDecLength1, float); +DECLARE_SOA_COLUMN(OmegaMassCasc1, omegaMassCasc1, float); +DECLARE_SOA_COLUMN(XiMassCasc1, xiMassCasc1, float); +DECLARE_SOA_COLUMN(CosPACasc1, cosPACasc1, float); +DECLARE_SOA_COLUMN(DcaBachPVCasc1, dcaBachPVCasc1, float); +DECLARE_SOA_COLUMN(DcaV0BachCasc1, dcaV0BachCasc1, float); +DECLARE_SOA_COLUMN(NSigmaKBach1, nSigmaKBach1, float); + +DECLARE_SOA_COLUMN(PtCasc2, ptCasc2, float); +DECLARE_SOA_COLUMN(EtaCasc2, etaCasc2, float); +DECLARE_SOA_COLUMN(PhiCasc2, phiCasc2, float); +DECLARE_SOA_COLUMN(CascDecLength2, cascDecLength2, float); +DECLARE_SOA_COLUMN(OmegaMassCasc2, omegaMassCasc2, float); +DECLARE_SOA_COLUMN(XiMassCasc2, xiMassCasc2, float); +DECLARE_SOA_COLUMN(CosPACasc2, cosPACasc2, float); +DECLARE_SOA_COLUMN(DcaBachPVCasc2, dcaBachPVCasc2, float); +DECLARE_SOA_COLUMN(DcaV0BachCasc2, dcaV0BachCasc2, float); +DECLARE_SOA_COLUMN(NSigmaKBach2, nSigmaKBach2, float); + +DECLARE_SOA_COLUMN(DoubleOmegaMass, doubleOmegaMass, float); +} // namespace DoubleCascTables + +DECLARE_SOA_TABLE(DoubleCascTable, "AOD", "DOUBLECASCTABLE", + DoubleCascTables::PtCasc1, + DoubleCascTables::EtaCasc1, + DoubleCascTables::PhiCasc1, + DoubleCascTables::CascDecLength1, + DoubleCascTables::OmegaMassCasc1, + DoubleCascTables::XiMassCasc1, + DoubleCascTables::CosPACasc1, + DoubleCascTables::DcaBachPVCasc1, + DoubleCascTables::DcaV0BachCasc1, + DoubleCascTables::NSigmaKBach1, + DoubleCascTables::PtCasc2, + DoubleCascTables::EtaCasc2, + DoubleCascTables::PhiCasc2, + DoubleCascTables::CascDecLength2, + DoubleCascTables::OmegaMassCasc2, + DoubleCascTables::XiMassCasc2, + DoubleCascTables::CosPACasc2, + DoubleCascTables::DcaBachPVCasc2, + DoubleCascTables::DcaV0BachCasc2, + DoubleCascTables::NSigmaKBach2, + DoubleCascTables::DoubleOmegaMass); + +} // namespace o2::aod + +#endif // PWGLF_DATAMODEL_LFDOUBLECASCTABLES_H_ diff --git a/PWGLF/DataModel/LFHypernucleiTables.h b/PWGLF/DataModel/LFHypernucleiTables.h index ba81c59b502..46955373222 100644 --- a/PWGLF/DataModel/LFHypernucleiTables.h +++ b/PWGLF/DataModel/LFHypernucleiTables.h @@ -56,12 +56,14 @@ DECLARE_SOA_COLUMN(NTPCclusHe, nTPCclusHe, uint8_t); // Number of DECLARE_SOA_COLUMN(NTPCclusPi, nTPCclusPi, uint8_t); // Number of TPC clusters of the Pi daughter DECLARE_SOA_COLUMN(TPCsignalHe, tpcSignalHe, uint16_t); // TPC signal of the He daughter DECLARE_SOA_COLUMN(TPCsignalPi, tpcSignalPi, uint16_t); // TPC signal of the Pi daughter -DECLARE_SOA_COLUMN(Tracked, tracked, bool); // bool: true for tracked candidates +DECLARE_SOA_COLUMN(TPCChi2He, tpcChi2He, float); // TPC chi2 of the He daughter +DECLARE_SOA_COLUMN(TrackedClSize, trackedClSize, int); // int: zero for non-tracked candidates DECLARE_SOA_COLUMN(Flags, flags, uint8_t); // Flags for PID in tracking (bits [0, 3] for negative daughter, [4,7] for positive daughter) DECLARE_SOA_COLUMN(TPCmomHe, tpcMomHe, float); // TPC momentum of the He daughter DECLARE_SOA_COLUMN(TPCmomPi, tpcMomPi, float); // TPC momentum of the Pi daughter DECLARE_SOA_COLUMN(ITSclusterSizesHe, itsClusterSizesHe, uint32_t); // ITS cluster size of the He daughter DECLARE_SOA_COLUMN(ITSclusterSizesPi, itsClusterSizesPi, uint32_t); // ITS cluster size of the Pi daughter +DECLARE_SOA_COLUMN(ITSclusterSizesHyp, itsClusterSizesHyp, uint32_t); // ITS cluster size of the Pi daughter DECLARE_SOA_COLUMN(DcaHe, dcaHe, float); // DCA between He daughter and V0 DECLARE_SOA_COLUMN(DcaPi, dcaPi, float); // DCA between pi daughter and V0 DECLARE_SOA_COLUMN(GenPt, genPt, float); // Pt of the hypertriton @@ -88,9 +90,9 @@ DECLARE_SOA_TABLE(DataHypCands, "AOD", "HYPCANDS", hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, - hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, - hyperrec::Flags, hyperrec::Tracked); + hyperrec::Flags, hyperrec::TrackedClSize); DECLARE_SOA_TABLE(DataHypCandsFlow, "AOD", "HYPCANDSFLOW", o2::soa::Index<>, @@ -106,9 +108,9 @@ DECLARE_SOA_TABLE(DataHypCandsFlow, "AOD", "HYPCANDSFLOW", hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, - hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, - hyperrec::Flags, hyperrec::Tracked); + hyperrec::Flags, hyperrec::TrackedClSize); DECLARE_SOA_TABLE(MCHypCands, "AOD", "MCHYPCANDS", o2::soa::Index<>, @@ -121,9 +123,9 @@ DECLARE_SOA_TABLE(MCHypCands, "AOD", "MCHYPCANDS", hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, - hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, - hyperrec::Flags, hyperrec::Tracked, + hyperrec::Flags, hyperrec::TrackedClSize, hyperrec::GenPt, hyperrec::GenPhi, hyperrec::GenEta, diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h index c61c1b25a7b..afc076d1a54 100644 --- a/PWGLF/DataModel/LFSlimNucleiTables.h +++ b/PWGLF/DataModel/LFSlimNucleiTables.h @@ -41,6 +41,7 @@ DECLARE_SOA_COLUMN(TPCfindableCls, tpcFindableCls, uint8_t); DECLARE_SOA_COLUMN(TPCcrossedRows, tpcCrossedRows, uint8_t); DECLARE_SOA_COLUMN(ITSclsMap, itsClsMap, uint8_t); DECLARE_SOA_COLUMN(TPCnCls, tpcNCls, uint8_t); +DECLARE_SOA_COLUMN(TPCnClsShared, tpcNClsShared, uint8_t); DECLARE_SOA_COLUMN(ITSclusterSizes, itsClusterSizes, uint32_t); DECLARE_SOA_COLUMN(gPt, genPt, float); DECLARE_SOA_COLUMN(gEta, genEta, float); @@ -83,6 +84,7 @@ DECLARE_SOA_TABLE(NucleiTable, "AOD", "NUCLEITABLE", NucleiTableNS::TPCcrossedRows, NucleiTableNS::ITSclsMap, NucleiTableNS::TPCnCls, + NucleiTableNS::TPCnClsShared, NucleiTableNS::ITSclusterSizes); DECLARE_SOA_TABLE(NucleiTableFlow, "AOD", "NUCLEITABLEFLOW", @@ -116,6 +118,7 @@ DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC", NucleiTableNS::TPCcrossedRows, NucleiTableNS::ITSclsMap, NucleiTableNS::TPCnCls, + NucleiTableNS::TPCnClsShared, NucleiTableNS::ITSclusterSizes, NucleiTableNS::gPt, NucleiTableNS::gEta, diff --git a/PWGLF/DataModel/LFStrangenessPIDTables.h b/PWGLF/DataModel/LFStrangenessPIDTables.h index 36a345b87ad..e689dc28141 100644 --- a/PWGLF/DataModel/LFStrangenessPIDTables.h +++ b/PWGLF/DataModel/LFStrangenessPIDTables.h @@ -137,15 +137,15 @@ DECLARE_SOA_COLUMN(BachTOFEventTime, bachTOFEventTime, float); //! bachelor tr // delta-times DECLARE_SOA_COLUMN(PosTOFDeltaTXiPi, posTOFDeltaTXiPi, float); //! positive track TOFDeltaT from pion <- lambda <- xi expectation -DECLARE_SOA_COLUMN(PosTOFDeltaTXiPr, posTOFDeltaTXiPr, float); //! positive track TOFDeltaT from pion <- lambda <- xi expectation +DECLARE_SOA_COLUMN(PosTOFDeltaTXiPr, posTOFDeltaTXiPr, float); //! positive track TOFDeltaT from proton <- lambda <- xi expectation DECLARE_SOA_COLUMN(NegTOFDeltaTXiPi, negTOFDeltaTXiPi, float); //! negative track TOFDeltaT from pion <- lambda <- xi expectation -DECLARE_SOA_COLUMN(NegTOFDeltaTXiPr, negTOFDeltaTXiPr, float); //! negative track TOFDeltaT from pion <- lambda <- xi expectation +DECLARE_SOA_COLUMN(NegTOFDeltaTXiPr, negTOFDeltaTXiPr, float); //! negative track TOFDeltaT from proton <- lambda <- xi expectation DECLARE_SOA_COLUMN(BachTOFDeltaTXiPi, bachTOFDeltaTXiPi, float); //! bachelor track TOFDeltaT from pion <- xi expectation DECLARE_SOA_COLUMN(PosTOFDeltaTOmPi, posTOFDeltaTOmPi, float); //! positive track TOFDeltaT from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(PosTOFDeltaTOmPr, posTOFDeltaTOmPr, float); //! positive track TOFDeltaT from pion <- lambda <- omega expectation +DECLARE_SOA_COLUMN(PosTOFDeltaTOmPr, posTOFDeltaTOmPr, float); //! positive track TOFDeltaT from proton <- lambda <- omega expectation DECLARE_SOA_COLUMN(NegTOFDeltaTOmPi, negTOFDeltaTOmPi, float); //! negative track TOFDeltaT from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float); //! negative track TOFDeltaT from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(BachTOFDeltaTOmPi, bachTOFDeltaTOmPi, float); //! bachelor track TOFDeltaT from pion <- omega expectation +DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float); //! negative track TOFDeltaT from proton <- lambda <- omega expectation +DECLARE_SOA_COLUMN(BachTOFDeltaTOmKa, bachTOFDeltaTOmKa, float); //! bachelor track TOFDeltaT from kaon <- omega expectation // n-sigmas DECLARE_SOA_COLUMN(TOFNSigmaXiLaPi, tofNSigmaXiLaPi, float); //! meson track NSigma from pion <- lambda <- xi expectation @@ -170,7 +170,7 @@ DECLARE_SOA_TABLE(CascTOFPIDs, "AOD", "CASCTOFPID", // processed information for cascdata::BachTOFDeltaTXiPi, cascdata::PosTOFDeltaTOmPi, cascdata::PosTOFDeltaTOmPr, cascdata::NegTOFDeltaTOmPi, cascdata::NegTOFDeltaTOmPr, - cascdata::BachTOFDeltaTOmPi); + cascdata::BachTOFDeltaTOmKa); DECLARE_SOA_TABLE(CascTOFNSigmas, "AOD", "CascTOFNSigmas", // Nsigmas for cascades cascdata::TOFNSigmaXiLaPi, cascdata::TOFNSigmaXiLaPr, cascdata::TOFNSigmaXiPi, cascdata::TOFNSigmaOmLaPi, cascdata::TOFNSigmaOmLaPr, cascdata::TOFNSigmaOmKa); diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 1eedee47828..2e77610a4c6 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -22,10 +22,31 @@ #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/McCollisionExtra.h" #include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGUD/DataModel/UDTables.h" namespace o2::aod { +namespace stracollision +{ +DECLARE_SOA_DYNAMIC_COLUMN(IsUPC, isUPC, //! check whether this is a UPC or hadronic collision + [](int value) -> bool { return value <= 2 ? true : false; }); +DECLARE_SOA_DYNAMIC_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, //! get the total sum of the FV0 A amplitudes + [](float value) -> float { return value; }); +DECLARE_SOA_DYNAMIC_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, //! get the total sum of the FT0 A amplitudes + [](float value) -> float { return value; }); +DECLARE_SOA_DYNAMIC_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, //! get the total sum of the FT0 C amplitudes + [](float value) -> float { return value; }); +DECLARE_SOA_DYNAMIC_COLUMN(TotalFDDAmplitudeA, totalFDDAmplitudeA, //! get the total sum of the FDD A amplitudes + [](float value) -> float { return value; }); +DECLARE_SOA_DYNAMIC_COLUMN(TotalFDDAmplitudeC, totalFDDAmplitudeC, //! get the total sum of the FDD C amplitudes + [](float value) -> float { return value; }); +DECLARE_SOA_DYNAMIC_COLUMN(EnergyCommonZNA, energyCommonZNA, //! get the total sum of the ZN A amplitudes + [](float value) -> float { return value; }); +DECLARE_SOA_DYNAMIC_COLUMN(EnergyCommonZNC, energyCommonZNC, //! get the total sum of the ZN A amplitudes + [](float value) -> float { return value; }); +} // namespace stracollision + //______________________________________________________ // Collision declarations for derived data analysis // this is optional but will ensure full flexibility @@ -35,13 +56,16 @@ DECLARE_SOA_TABLE(StraCollisions, "AOD", "STRACOLLISION", //! basic collision pr DECLARE_SOA_TABLE(StraCents, "AOD", "STRACENTS", //! centrality percentiles cent::CentFT0M, cent::CentFT0A, cent::CentFT0C, cent::CentFV0A); +// !!! DEPRECATED TABLE: StraRawCents_000 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001 DECLARE_SOA_TABLE(StraRawCents_000, "AOD", "STRARAWCENTS", //! debug information mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, mult::MultNTracksPVeta1); +// !!! DEPRECATED TABLE: StraRawCents_001 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_001, "AOD", "STRARAWCENTS", 1, //! debug information mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors mult::MultNTracksPVeta1, // track multiplicities mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals mult::MultZEM2, mult::MultZPA, mult::MultZPC); +// !!! DEPRECATED TABLE: StraRawCents_002 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_002, "AOD", "STRARAWCENTS", 2, //! debug information mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors mult::MultNTracksPVeta1, // track multiplicities with eta cut for INEL>0 @@ -49,6 +73,7 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_002, "AOD", "STRARAWCENTS", 2, mult::MultAllTracksTPCOnly, mult::MultAllTracksITSTPC, // track multiplicities, all, no eta cut mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals mult::MultZEM2, mult::MultZPA, mult::MultZPC); +// !!! DEPRECATED TABLE: StraRawCents_003 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_003, "AOD", "STRARAWCENTS", 3, //! debug information mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors mult::MultNTracksPVeta1, // track multiplicities with eta cut for INEL>0 @@ -59,6 +84,7 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_003, "AOD", "STRARAWCENTS", 3, //! mult::MultAllTracksITSTPC, // ITSTPC track multiplicities, all, no eta cut mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals mult::MultZEM2, mult::MultZPA, mult::MultZPC); +// !!! DEPRECATED TABLE: StraRawCents_004 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_004, "AOD", "STRARAWCENTS", 4, //! debug information mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors mult::MultNTracksPVeta1, // track multiplicities with eta cut for INEL>0 @@ -70,8 +96,40 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_004, "AOD", "STRARAWCENTS", 4, //! mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals mult::MultZEM2, mult::MultZPA, mult::MultZPC, evsel::NumTracksInTimeRange); // add occupancy as extra -DECLARE_SOA_TABLE(StraEvSels, "AOD", "STRAEVSELS", //! event selection: sel8 +DECLARE_SOA_TABLE(StraEvSels_000, "AOD", "STRAEVSELS", //! event selection: sel8 evsel::Sel8, evsel::Selection); +DECLARE_SOA_TABLE_VERSIONED(StraEvSels_001, "AOD", "STRAEVSELS", 1, //! debug information + evsel::Sel8, evsel::Selection, //! event selection: sel8 + mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors + mult::MultFDDA, mult::MultFDDC, + mult::MultNTracksPVeta1, // track multiplicities with eta cut for INEL>0 + mult::MultPVTotalContributors, // number of PV contribs total + mult::MultNTracksGlobal, // global track multiplicities + mult::MultNTracksITSTPC, // track multiplicities, PV contribs, no eta cut + mult::MultAllTracksTPCOnly, // TPConly track multiplicities, all, no eta cut + mult::MultAllTracksITSTPC, // ITSTPC track multiplicities, all, no eta cut + mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals + mult::MultZEM2, mult::MultZPA, mult::MultZPC, + evsel::NumTracksInTimeRange, // add occupancy as extra + udcollision::GapSide, // UPC info: 0 for side A, 1 for side C, 2 for both sides, 3 neither A or C, 4 not enough or too many pv contributors + udcollision::TotalFT0AmplitudeA, // UPC info: re-assigned FT0-A amplitude, in case of SG event, from the most active bc + udcollision::TotalFT0AmplitudeC, // UPC info: re-assigned FT0-C amplitude, in case of SG event, from the most active bc + udcollision::TotalFV0AmplitudeA, // UPC info: re-assigned FV0-A amplitude, in case of SG event, from the most active bc + udcollision::TotalFDDAmplitudeA, // UPC info: re-assigned FDD-A amplitude, in case of SG event, from the most active bc + udcollision::TotalFDDAmplitudeC, // UPC info: re-assigned FDD-C amplitude, in case of SG event, from the most active bc + udzdc::EnergyCommonZNA, // UPC info: re-assigned ZN-A amplitude, in case of SG event, from the most active bc + udzdc::EnergyCommonZNC, // UPC info: re-assigned ZN-C amplitude, in case of SG event, from the most active bc + + // Dynamic columns for manipulating information + // stracollision::TotalFV0AmplitudeA, + // stracollision::TotalFT0AmplitudeA, + // stracollision::TotalFT0AmplitudeC, + // stracollision::TotalFDDAmplitudeA, + // stracollision::TotalFDDAmplitudeC, + // stracollision::EnergyCommonZNA, + // stracollision::EnergyCommonZNC, + stracollision::IsUPC); + DECLARE_SOA_TABLE(StraFT0AQVs, "AOD", "STRAFT0AQVS", //! t0a Qvec qvec::QvecFT0ARe, qvec::QvecFT0AIm, qvec::SumAmplFT0A); DECLARE_SOA_TABLE(StraFT0CQVs, "AOD", "STRAFT0CQVS", //! t0c Qvec @@ -89,6 +147,7 @@ DECLARE_SOA_TABLE(StraStamps, "AOD", "STRASTAMPS", //! information for ID-ing ma bc::RunNumber, timestamp::Timestamp); using StraRawCents = StraRawCents_004; +using StraEvSels = StraEvSels_001; using StraCollision = StraCollisions::iterator; using StraCent = StraCents::iterator; diff --git a/PWGLF/DataModel/SPCalibrationTables.h b/PWGLF/DataModel/SPCalibrationTables.h new file mode 100644 index 00000000000..82d622e2c8c --- /dev/null +++ b/PWGLF/DataModel/SPCalibrationTables.h @@ -0,0 +1,71 @@ +// 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 SPCalibrationTables.h +/// +/// author: prottay das 07/09/2024 +/// email: prottay.das@cern.ch + +#ifndef PWGLF_DATAMODEL_SPCALIBRATIONTABLES_H_ +#define PWGLF_DATAMODEL_SPCALIBRATIONTABLES_H_ + +#include + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +namespace spcalibrationtable +{ +DECLARE_SOA_COLUMN(TriggerEvent, triggerevent, bool); +DECLARE_SOA_COLUMN(TriggerEventRunNo, triggereventrunno, int); +DECLARE_SOA_COLUMN(Cent, cent, float); +DECLARE_SOA_COLUMN(Vz, vz, float); +DECLARE_SOA_COLUMN(ZNAEN1, znaen1, float); +DECLARE_SOA_COLUMN(ZNAEN2, znaen2, float); +DECLARE_SOA_COLUMN(ZNAEN3, znaen3, float); +DECLARE_SOA_COLUMN(ZNAEN4, znaen4, float); +DECLARE_SOA_COLUMN(ZNCEN1, zncen1, float); +DECLARE_SOA_COLUMN(ZNCEN2, zncen2, float); +DECLARE_SOA_COLUMN(ZNCEN3, zncen3, float); +DECLARE_SOA_COLUMN(ZNCEN4, zncen4, float); +DECLARE_SOA_COLUMN(QXZDCA, qxZDCA, float); +DECLARE_SOA_COLUMN(QXZDCC, qxZDCC, float); +DECLARE_SOA_COLUMN(QYZDCA, qyZDCA, float); +DECLARE_SOA_COLUMN(QYZDCC, qyZDCC, float); +DECLARE_SOA_COLUMN(PsiZDCC, psiZDCC, float); +DECLARE_SOA_COLUMN(PsiZDCA, psiZDCA, float); +} // namespace spcalibrationtable +DECLARE_SOA_TABLE(SPCalibrationTables, "AOD", "SPCALCOLS", + spcalibrationtable::TriggerEvent, + spcalibrationtable::TriggerEventRunNo, + spcalibrationtable::Cent, + spcalibrationtable::Vz, + spcalibrationtable::ZNAEN1, + spcalibrationtable::ZNAEN2, + spcalibrationtable::ZNAEN3, + spcalibrationtable::ZNAEN4, + spcalibrationtable::ZNCEN1, + spcalibrationtable::ZNCEN2, + spcalibrationtable::ZNCEN3, + spcalibrationtable::ZNCEN4, + spcalibrationtable::QXZDCA, + spcalibrationtable::QXZDCC, + spcalibrationtable::QYZDCA, + spcalibrationtable::QYZDCC, + spcalibrationtable::PsiZDCC, + spcalibrationtable::PsiZDCA); +using SPCalibrationTable = SPCalibrationTables::iterator; +} // namespace o2::aod +#endif // PWGLF_DATAMODEL_SPCALIBRATIONTABLES_H_ diff --git a/PWGLF/DataModel/Vtx3BodyTables.h b/PWGLF/DataModel/Vtx3BodyTables.h index 0e74ec86372..f1b88dfb455 100644 --- a/PWGLF/DataModel/Vtx3BodyTables.h +++ b/PWGLF/DataModel/Vtx3BodyTables.h @@ -43,6 +43,9 @@ DECLARE_SOA_COLUMN(Z, z, float); //! decay position Z // Saved from finding: DCAs DECLARE_SOA_COLUMN(DCAVtxDaughters, dcaVtxdaughters, float); //! DCA among daughters +DECLARE_SOA_COLUMN(DCAXYTrack0ToPV, dcaXYtrack0topv, float); //! DCAXY of prong0 to PV +DECLARE_SOA_COLUMN(DCAXYTrack1ToPV, dcaXYtrack1topv, float); //! DCAXY of prong1 to PV +DECLARE_SOA_COLUMN(DCAXYTrack2ToPV, dcaXYtrack2topv, float); //! DCAXY of prong2 to PV DECLARE_SOA_COLUMN(DCATrack0ToPV, dcatrack0topv, float); //! DCA of prong0 to PV DECLARE_SOA_COLUMN(DCATrack1ToPV, dcatrack1topv, float); //! DCA of prong1 to PV DECLARE_SOA_COLUMN(DCATrack2ToPV, dcatrack2topv, float); //! DCA of prong2 to PV @@ -132,6 +135,7 @@ DECLARE_SOA_TABLE_FULL(StoredVtx3BodyDatas, "Vtx3BodyDatas", "AOD", "Vtx3BodyDAT vtx3body::PxTrack1, vtx3body::PyTrack1, vtx3body::PzTrack1, vtx3body::PxTrack2, vtx3body::PyTrack2, vtx3body::PzTrack2, vtx3body::DCAVtxDaughters, + vtx3body::DCAXYTrack0ToPV, vtx3body::DCAXYTrack1ToPV, vtx3body::DCAXYTrack2ToPV, vtx3body::DCATrack0ToPV, vtx3body::DCATrack1ToPV, vtx3body::DCATrack2ToPV, vtx3body::TOFNSigmaBachDe, @@ -246,15 +250,19 @@ DECLARE_SOA_COLUMN(TPCNSigmaPion, tpcNSigmaPion, float); //! nsigma of T DECLARE_SOA_COLUMN(TPCNSigmaBachelor, tpcNSigmaBachelor, float); //! nsigma of TPC PID of the bachelor daughter DECLARE_SOA_COLUMN(TOFNSigmaBachelor, tofNSigmaBachelor, float); //! nsigma of TOF PID of the bachelor daughter // DCA to PV -DECLARE_SOA_COLUMN(DCAProtonToPV, dcaProtontoPV, float); //! DCA of the proton daughter to pv -DECLARE_SOA_COLUMN(DCAPionToPV, dcaPiontoPV, float); //! DCA of the pion daughter to pv -DECLARE_SOA_COLUMN(DCABachelorToPV, dcaBachelortoPV, float); //! DCA of the bachelor daughter to pv +DECLARE_SOA_COLUMN(DCAXYProtonToPV, dcaxyProtontoPV, float); //! DCAXY of the proton daughter to pv +DECLARE_SOA_COLUMN(DCAXYPionToPV, dcaxyPiontoPV, float); //! DCAXY of the pion daughter to pv +DECLARE_SOA_COLUMN(DCAXYBachelorToPV, dcaxyBachelortoPV, float); //! DCAXY of the bachelor daughter to pv +DECLARE_SOA_COLUMN(DCAProtonToPV, dcaProtontoPV, float); //! DCA of the proton daughter to pv +DECLARE_SOA_COLUMN(DCAPionToPV, dcaPiontoPV, float); //! DCA of the pion daughter to pv +DECLARE_SOA_COLUMN(DCABachelorToPV, dcaBachelortoPV, float); //! DCA of the bachelor daughter to pv // for MC DECLARE_SOA_COLUMN(GenP, genP, float); // P of the hypertriton DECLARE_SOA_COLUMN(GenPt, genPt, float); // pT of the hypertriton DECLARE_SOA_COLUMN(GenCt, genCt, float); // ct of the hypertriton DECLARE_SOA_COLUMN(GenPhi, genPhi, float); // Phi of the hypertriton DECLARE_SOA_COLUMN(GenEta, genEta, float); // Eta of the hypertriton +DECLARE_SOA_COLUMN(GenRapidity, genRapidity, float); // Rapidity of the hypertriton DECLARE_SOA_COLUMN(IsReco, isReco, bool); // bool: true for reco DECLARE_SOA_COLUMN(IsSignal, isSignal, bool); // bool: true for signal DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); // pdgCode of the mcparticle, -1 for fake pair @@ -284,6 +292,7 @@ DECLARE_SOA_TABLE(Hyp3BodyCands, "AOD", "HYP3BODYCANDS", hyp3body::ITSNclusSizeProton, hyp3body::ITSNclusSizePion, hyp3body::ITSNclusSizeBachelor, hyp3body::TPCNSigmaProton, hyp3body::TPCNSigmaPion, hyp3body::TPCNSigmaBachelor, hyp3body::TOFNSigmaBachelor, + hyp3body::DCAXYProtonToPV, hyp3body::DCAXYPionToPV, hyp3body::DCAXYBachelorToPV, hyp3body::DCAProtonToPV, hyp3body::DCAPionToPV, hyp3body::DCABachelorToPV); // output table for MC @@ -309,6 +318,7 @@ DECLARE_SOA_TABLE(MCHyp3BodyCands, "AOD", "MCHYP3BODYCANDS", hyp3body::ITSNclusSizeProton, hyp3body::ITSNclusSizePion, hyp3body::ITSNclusSizeBachelor, hyp3body::TPCNSigmaProton, hyp3body::TPCNSigmaPion, hyp3body::TPCNSigmaBachelor, hyp3body::TOFNSigmaBachelor, + hyp3body::DCAXYProtonToPV, hyp3body::DCAXYPionToPV, hyp3body::DCAXYBachelorToPV, hyp3body::DCAProtonToPV, hyp3body::DCAPionToPV, hyp3body::DCABachelorToPV, // MC information hyp3body::GenP, @@ -316,6 +326,7 @@ DECLARE_SOA_TABLE(MCHyp3BodyCands, "AOD", "MCHYP3BODYCANDS", hyp3body::GenCt, hyp3body::GenPhi, hyp3body::GenEta, + hyp3body::GenRapidity, hyp3body::IsSignal, hyp3body::IsReco, hyp3body::PdgCode, diff --git a/PWGLF/DataModel/pidTOFGeneric.h b/PWGLF/DataModel/pidTOFGeneric.h index f1db0aef03a..047ec6aa477 100644 --- a/PWGLF/DataModel/pidTOFGeneric.h +++ b/PWGLF/DataModel/pidTOFGeneric.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef PIDTOFGENERIC_H_ -#define PIDTOFGENERIC_H_ +#ifndef PWGLF_DATAMODEL_PIDTOFGENERIC_H_ +#define PWGLF_DATAMODEL_PIDTOFGENERIC_H_ #include "CommonDataFormat/InteractionRecord.h" #include "Common/Core/PID/PIDTOF.h" @@ -155,4 +155,4 @@ class TofPidNewCollision } // namespace pidtofgeneric } // namespace o2::aod -#endif +#endif // PWGLF_DATAMODEL_PIDTOFGENERIC_H_ diff --git a/PWGLF/TableProducer/Common/CMakeLists.txt b/PWGLF/TableProducer/Common/CMakeLists.txt index a3c26273a81..e68b511978d 100644 --- a/PWGLF/TableProducer/Common/CMakeLists.txt +++ b/PWGLF/TableProducer/Common/CMakeLists.txt @@ -15,6 +15,11 @@ o2physics_add_dpl_workflow(epvector PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(spvector + SOURCES spvector.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(tpcpid SOURCES lfTPCPID.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -28,4 +33,4 @@ o2physics_add_dpl_workflow(zdcsp o2physics_add_dpl_workflow(mc-centrality SOURCES mcCentrality.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGLF/TableProducer/Common/spvector.cxx b/PWGLF/TableProducer/Common/spvector.cxx new file mode 100644 index 00000000000..bf9074e38e1 --- /dev/null +++ b/PWGLF/TableProducer/Common/spvector.cxx @@ -0,0 +1,345 @@ +// 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. +// +// \author: prottay das 07/09/2024 +// \email: prottay.das@cern.ch + +// C++/ROOT includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include "Math/Vector4D.h" +#include "TRandom3.h" +#include "TF1.h" + +// o2Physics includes. +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/FT0Corrected.h" +#include "FT0Base/Geometry.h" +#include "FV0Base/Geometry.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/TableProducer/PID/pidTOFBase.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/CCDB/ctpRateFetcher.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "PWGLF/DataModel/SPCalibrationTables.h" + +// o2 includes. +#include "CCDB/CcdbApi.h" +#include "CCDB/BasicCCDBManager.h" +#include "DetectorsCommonDataFormats/AlignParam.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::physics; + +using BCsRun3 = soa::Join; + +struct spvector { + + Produces spcalibrationtable; + + // Configurables. + 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; + + // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutCentrality{"cfgCutCentrality", 80.0f, "Centrality cut"}; + Configurable cfgCutPT{"cfgCutPT", 0.15, "PT cut on daughter track"}; + Configurable cfgCutPTMax{"cfgCutPTMax", 3.0, "Max PT cut on daughter track"}; + Configurable cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"}; + Configurable cfgMinEta{"cfgMinEta", 0.1, "Min Eta cut on daughter track"}; + Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"}; + Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; + + Configurable QxyNbins{"QxyNbins", 100, "Number of bins in QxQy histograms"}; + Configurable lbinQxy{"lbinQxy", -5.0, "lower bin value in QxQy histograms"}; + Configurable hbinQxy{"hbinQxy", 5.0, "higher bin value in QxQy histograms"}; + Configurable ZDCgainNbins{"ZDCgainNbins", 500, "Number of bins in Gaineq histograms"}; + Configurable lbinZDCgain{"lbinZDCgain", 0.0, "lower bin value in Gaineq histograms"}; + Configurable hbinZDCgain{"hbinZDCgain", 1000.0, "higher bin value in Gaineq histograms"}; + + Configurable useGainCallib{"useGainCallib", false, "use gain calibration"}; + Configurable useRecentere{"useRecentere", false, "use Recentering"}; + Configurable useShift{"useShift", false, "use Shift"}; + Configurable ConfGainPath{"ConfGainPath", "Users/p/prottay/My/Object/test100", "Path to gain calibration"}; + Configurable ConfRecentere{"ConfRecentere", "Users/p/prottay/My/Object/NewPbPbpass4_23082024/recenter", "Path for recentere"}; + Configurable ConfShift{"ConfShift", "Users/p/prottay/My/Object/Finaltest2/recenereall", "Path for Shift"}; + + ConfigurableAxis configAxisCentrality{"configAxisCentrality", {80, 0.0, 80}, "centrality bining"}; + // ConfigurableAxis configAxisZDCgain{"configAxisZDCgain", {ZDCgainNbins, lbinZDCgain, hbinZDCgain}, "gainamplitude bining"}; + // ConfigurableAxis configAxisQx{"configAxisQx", {QxyNbins, lbinQxy, hbinQxy}, "qx bining"}; + // ConfigurableAxis configAxisQy{"configAxisQy", {QxyNbins, lbinQxy, hbinQxy}, "qy bining"}; + + // Event selection cuts - Alex + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultMultPVCut = nullptr; + + int mRunNumber{-1}; + + template + bool eventSelected(TCollision collision, const float& centrality) + { + auto multNTracksPV = collision.multNTracksPV(); + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + return 0; + + return 1; + } + + void initCCDB(BCsRun3::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + mRunNumber = bc.runNumber(); + } + + void init(o2::framework::InitContext&) + { + + std::vector occupancyBinning = {0.0, 500.0, 1000.0, 1500.0, 2000.0, 3000.0, 4000.0, 5000.0, 50000.0}; + + const AxisSpec centAxis{configAxisCentrality, "V0M (%)"}; + + // AxisSpec amplitudeZDC = {configAxisZDCgain, "ZDC amplitude"}; + AxisSpec amplitudeZDC = {ZDCgainNbins, lbinZDCgain, hbinZDCgain, "ZDC amplitude"}; + AxisSpec channelZDCAxis = {8, 0.0, 8.0, "ZDC tower"}; + AxisSpec qxZDCAxis = {QxyNbins, lbinQxy, hbinQxy, "Qx"}; + AxisSpec qyZDCAxis = {QxyNbins, lbinQxy, hbinQxy, "Qy"}; + AxisSpec phiAxis = {50, -6.28, 6.28, "phi"}; + AxisSpec vzAxis = {20, -10, 10, "vz"}; + + histos.add("hCentrality", "hCentrality", kTH1F, {{8, 0, 80.0}}); + histos.add("Vz", "Vz", kTH1F, {vzAxis}); + + histos.add("hpQxZDCAC", "hpQxZDCAC", kTProfile, {centAxis}); + histos.add("hpQyZDCAC", "hpQyZDCAC", kTProfile, {centAxis}); + histos.add("hpQxZDCAQyZDCC", "hpQxZDCAQyZDCC", kTProfile, {centAxis}); + histos.add("hpQxZDCCQyZDCA", "hpQxZDCCQyZDCA", kTProfile, {centAxis}); + histos.add("QxZDCC", "QxZDCC", kTH2F, {centAxis, qxZDCAxis}); + histos.add("QyZDCC", "QyZDCC", kTH2F, {centAxis, qyZDCAxis}); + histos.add("QxZDCA", "QxZDCA", kTH2F, {centAxis, qxZDCAxis}); + histos.add("QyZDCA", "QyZDCA", kTH2F, {centAxis, qyZDCAxis}); + histos.add("PsiZDCC", "PsiZDCC", kTH2F, {centAxis, phiAxis}); + histos.add("PsiZDCA", "PsiZDCA", kTH2F, {centAxis, phiAxis}); + histos.add("ZDCAmp", "ZDCAmp", kTProfile2D, {channelZDCAxis, vzAxis}); + histos.add("hZDCAmp", "hZDCAmp", kTH3F, {channelZDCAxis, vzAxis, amplitudeZDC}); + + // Event selection cut additional - Alex + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x)", 0, 100); + fMultCutLow->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x)", 0, 100); + fMultCutHigh->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); + fMultMultPVCut = new TF1("fMultMultPVCut", "[0]+[1]*x+[2]*x*x", 0, 5000); + fMultMultPVCut->SetParameters(-0.1, 0.785, -4.7e-05); + + 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 currentRunNumber = -999; + int lastRunNumber = -999; + TH2D* gainprofile; + TH2D* hrecentere; + + // Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); + // Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + + using MyCollisions = soa::Join; + // using MyTracks = soa::Filtered>; + + Preslice zdcPerCollision = aod::collision::bcId; + + // void process(MyCollisions::iterator const& collision, aod::FT0s const& /*ft0s*/, BCsRun3 const& bcs, aod::Zdcs const&, MyTracks const&) + void process(MyCollisions::iterator const& collision, aod::FT0s const& /*ft0s*/, BCsRun3 const& bcs, aod::Zdcs const&) + { + + auto centrality = collision.centFT0C(); + + if (bcs.size() != 0) { + gRandom->SetSeed(bcs.iteratorAt(0).globalBC()); + } + + auto bc = collision.foundBC_as(); + if (!bc.has_zdc()) { + return; + } + + currentRunNumber = collision.foundBC_as().runNumber(); + auto vz = collision.posZ(); + bool triggerevent = false; + + float psiZDCC = -99; + float psiZDCA = -99; + auto qxZDCA = 0.0; + auto qxZDCC = 0.0; + auto qyZDCA = 0.0; + auto qyZDCC = 0.0; + auto sumA = 0.0; + auto sumC = 0.0; + + auto zdc = bc.zdc(); + auto zncEnergy = zdc.energySectorZNC(); + auto znaEnergy = zdc.energySectorZNA(); + + if (znaEnergy[0] < 0.0 || znaEnergy[1] < 0.0 || znaEnergy[2] < 0.0 || znaEnergy[3] < 0.0) + return; + if (zncEnergy[0] < 0.0 || zncEnergy[1] < 0.0 || zncEnergy[2] < 0.0 || zncEnergy[3] < 0.0) + return; + + if (collision.sel8() && centrality < cfgCutCentrality && TMath::Abs(vz) < cfgCutVertex && collision.has_foundFT0() && eventSelected(collision, centrality) && collision.selection_bit(aod::evsel::kNoTimeFrameBorder) && collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + triggerevent = true; + if (useGainCallib && (currentRunNumber != lastRunNumber)) { + gainprofile = ccdb->getForTimeStamp(ConfGainPath.value, bc.timestamp()); + } + + histos.fill(HIST("hCentrality"), centrality); + histos.fill(HIST("Vz"), vz); + + initCCDB(bc); + + auto gainequal = 1.0; + constexpr float x[4] = {-1.75, 1.75, -1.75, 1.75}; + constexpr float y[4] = {-1.75, -1.75, 1.75, 1.75}; + + for (std::size_t iChA = 0; iChA < 8; iChA++) { + auto chanelid = iChA; + if (useGainCallib) { + gainequal = gainprofile->GetBinContent(gainprofile->FindBin(chanelid)); + } + + if (iChA < 4) { + + if (znaEnergy[iChA] <= 0.0) { + return; + } else { + float ampl = gainequal * znaEnergy[iChA]; + qxZDCA = qxZDCA + ampl * x[iChA]; + qyZDCA = qyZDCA + ampl * y[iChA]; + sumA = sumA + ampl; + histos.fill(HIST("ZDCAmp"), chanelid + 0.5, vz, ampl); + histos.fill(HIST("hZDCAmp"), chanelid + 0.5, vz, ampl); + } + } else { + + if (zncEnergy[iChA - 4] <= 0.0) { + return; + } else { + float ampl = gainequal * zncEnergy[iChA - 4]; + qxZDCC = qxZDCC + ampl * x[iChA - 4]; + qyZDCC = qyZDCC + ampl * y[iChA - 4]; + sumC = sumC + ampl; + histos.fill(HIST("ZDCAmp"), chanelid + 0.5, vz, ampl); + histos.fill(HIST("hZDCAmp"), chanelid + 0.5, vz, ampl); + } + } + } + + if (sumA > 0) { + qxZDCA = qxZDCA / sumA; + qyZDCA = qyZDCA / sumA; + } + if (sumC > 0) { + qxZDCC = qxZDCC / sumC; + qyZDCC = qyZDCC / sumC; + } + + if (sumA <= 1e-4 || sumC <= 1e-4) { + qxZDCA = 0.0; + qxZDCC = 0.0; + qyZDCA = 0.0; + qyZDCC = 0.0; + return; + } + + if (useRecentere && (currentRunNumber != lastRunNumber)) { + hrecentere = ccdb->getForTimeStamp(ConfRecentere.value, bc.timestamp()); + } + + if (useRecentere) { + + qxZDCA = (qxZDCA - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 0.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 0.5)); + qyZDCA = (qyZDCA - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 1.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 1.5)); + qxZDCC = (qxZDCC - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 2.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 2.5)); + qyZDCC = (qyZDCC - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 3.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 3.5)); + } + + psiZDCC = 1.0 * TMath::ATan2(qyZDCC, qxZDCC); + psiZDCA = 1.0 * TMath::ATan2(qyZDCA, qxZDCA); + + histos.fill(HIST("hpQxZDCAC"), centrality, (qxZDCA * qxZDCC)); + histos.fill(HIST("hpQyZDCAC"), centrality, (qyZDCA * qyZDCC)); + histos.fill(HIST("hpQxZDCAQyZDCC"), centrality, (qxZDCA * qyZDCC)); + histos.fill(HIST("hpQxZDCCQyZDCA"), centrality, (qxZDCC * qyZDCA)); + histos.fill(HIST("QxZDCC"), centrality, qxZDCC); + histos.fill(HIST("QyZDCC"), centrality, qyZDCC); + histos.fill(HIST("QxZDCA"), centrality, qxZDCA); + histos.fill(HIST("QyZDCA"), centrality, qyZDCA); + histos.fill(HIST("PsiZDCA"), centrality, psiZDCA); + histos.fill(HIST("PsiZDCC"), centrality, psiZDCC); + + lastRunNumber = currentRunNumber; + } + + spcalibrationtable(triggerevent, lastRunNumber, centrality, vz, znaEnergy[0], znaEnergy[1], znaEnergy[2], znaEnergy[3], zncEnergy[0], zncEnergy[1], zncEnergy[2], zncEnergy[3], qxZDCA, qyZDCA, qxZDCC, qyZDCC, psiZDCC, psiZDCA); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index dc313063a19..aef355695a9 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -454,14 +454,17 @@ struct decay3bodyBuilder { auto Track0Par = getTrackPar(t0); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); auto Track0dcaXY = dcaInfo[0]; + auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]); auto Track1Par = getTrackPar(t1); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); auto Track1dcaXY = dcaInfo[0]; + auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]); auto Track2Par = getTrackPar(t2); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); auto Track2dcaXY = dcaInfo[0]; + auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]); auto Track0 = getTrackParCov(t0); auto Track1 = getTrackParCov(t1); @@ -517,6 +520,7 @@ struct decay3bodyBuilder { p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], fitter3body.getChi2AtPCACandidate(), Track0dcaXY, Track1dcaXY, Track2dcaXY, + Track0dca, Track1dca, Track2dca, tofNsigmaDe); } } diff --git a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx index 5f6d8e7aa00..88cd22d1692 100644 --- a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx +++ b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx @@ -303,7 +303,7 @@ struct ebyeMaker { track.tpcNClsShared() > v0trackNsharedClusTpc) { return false; } - if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2) { + if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2 || doprocessMiniMcRun2) { if (!(track.trackType() & o2::aod::track::Run2Track) || !(track.flags() & o2::aod::track::TPCrefit)) { return false; @@ -332,7 +332,7 @@ struct ebyeMaker { track.itsChi2NCl() > 36.f) { return false; } - if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2) { + if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2 || doprocessMiniMcRun2) { if (!(track.trackType() & o2::aod::track::Run2Track) || !(track.flags() & o2::aod::track::TPCrefit) || !(track.flags() & o2::aod::track::ITSrefit)) { @@ -362,7 +362,7 @@ struct ebyeMaker { auto timestamp = bc.timestamp(); o2::parameters::GRPObject* grpo = 0x0; o2::parameters::GRPMagField* grpmag = 0x0; - if (doprocessRun2 || doprocessMcRun2 || doprocessMiniRun2) { + if (doprocessRun2 || doprocessMcRun2 || doprocessMiniRun2 || doprocessMiniMcRun2) { auto grpPath{"GLO/GRP/GRP"}; grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); if (!grpo) { @@ -397,7 +397,7 @@ struct ebyeMaker { template float getOuterPID(T const& track) { - if (doprocessMiniRun2) { + if (doprocessMiniRun2 || doprocessMiniMcRun2) { if (track.hasTOF() && track.pt() > antipPtTof) return track.tofNSigmaPr(); // else if (track.pt() < antipPtTof && track.pt() > antipPtMin) { @@ -409,6 +409,26 @@ struct ebyeMaker { return -999.f; } + float getV0M(int64_t const id, float const zvtx, aod::FV0As const& fv0as, aod::FV0Cs const& fv0cs) + { + auto fv0a = fv0as.rawIteratorAt(id); + auto fv0c = fv0cs.rawIteratorAt(id); + float multFV0A = 0; + float multFV0C = 0; + for (float amplitude : fv0a.amplitude()) { + multFV0A += amplitude; + } + + for (float amplitude : fv0c.amplitude()) { + multFV0C += amplitude; + } + + float v0m = multFV0A * Run2V0MInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0A->FindFixBin(zvtx)) + + multFV0C * Run2V0MInfo.mhVtxAmpCorrV0C->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0C->FindFixBin(zvtx)); + + return v0m; + } + template int getTrackSelMask(T const& track) { @@ -605,7 +625,7 @@ struct ebyeMaker { if (!posSelect || !negSelect) continue; - if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2) { + if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2 || doprocessMiniMcRun2) { bool checkPosPileUp = posTrack.hasTOF() || (posTrack.flags() & o2::aod::track::ITSrefit); bool checkNegPileUp = negTrack.hasTOF() || (negTrack.flags() & o2::aod::track::ITSrefit); if (!checkPosPileUp && !checkNegPileUp) { @@ -1017,20 +1037,7 @@ struct ebyeMaker { if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kAliEventCutsAccepted))) continue; - auto fv0a = fv0as.rawIteratorAt(bc.globalIndex()); - auto fv0c = fv0cs.rawIteratorAt(bc.globalIndex()); - float multFV0A = 0; - float multFV0C = 0; - for (float amplitude : fv0a.amplitude()) { - multFV0A += amplitude; - } - - for (float amplitude : fv0c.amplitude()) { - multFV0C += amplitude; - } - - float v0m = multFV0A * Run2V0MInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0A->FindFixBin(collision.posZ())) + - multFV0C * Run2V0MInfo.mhVtxAmpCorrV0C->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0C->FindFixBin(collision.posZ())); + float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); histos.fill(HIST("QA/zVtx"), collision.posZ()); @@ -1194,6 +1201,54 @@ struct ebyeMaker { } } PROCESS_SWITCH(ebyeMaker, processMcRun2, "process MC (Run 2)", false); + + void processMiniMcRun2(soa::Join const& collisions, aod::McCollisions const& /*mcCollisions*/, TracksFullPID const& tracks, aod::FV0As const& fv0as, aod::FV0Cs const& fv0cs, aod::V0s const& V0s, aod::McParticles const& mcParticles, aod::McTrackLabels const& mcLab, BCsWithRun2Info const&) + { + + for (const auto& collision : collisions) { + auto bc = collision.bc_as(); + initCCDB(bc); + + if (std::abs(collision.posZ()) > zVtxMax) + continue; + + if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kAliEventCutsAccepted))) + continue; + + float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); + float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + + histos.fill(HIST("QA/zVtx"), collision.posZ()); + + const uint64_t collIdx = collision.globalIndex(); + auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0, collIdx); + V0Table_thisCollision.bindExternalIndices(&tracks); + + fillMcEvent(collision, tracks, V0Table_thisCollision, cV0M, mcParticles, mcLab); + fillMcGen(mcParticles, mcLab, collision.mcCollisionId()); + + miniCollTable(std::abs(collision.posZ()), 0x0, nTrackletsColl, cV0M); + + for (auto& candidateTrack : candidateTracks[0]) { // protons + auto tk = tracks.rawIteratorAt(candidateTrack.globalIndex); + float outerPID = getOuterPID(tk); + candidateTrack.outerPID = tk.pt() < antipPtTof ? candidateTrack.outerPID : outerPID; + int selMask = getTrackSelMask(candidateTrack); + if (candidateTrack.outerPID < -4) + continue; + mcMiniTrkTable( + miniCollTable.lastIndex(), + candidateTrack.pt, + std::abs(candidateTrack.eta) * 10., + selMask, + candidateTrack.outerPID, + candidateTrack.genpt, + candidateTrack.geneta, + candidateTrack.isreco); + } + } + } + PROCESS_SWITCH(ebyeMaker, processMiniMcRun2, "process mini tables for mc(Run 2)", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx index a085e6cae51..8951e0eba29 100644 --- a/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx @@ -102,6 +102,7 @@ struct hyperCandidate { std::array gDecVtx; uint16_t tpcSignalHe3 = 0u; uint16_t tpcSignalPi = 0u; + float tpcChi2He3 = 0.f; uint8_t nTPCClustersHe3 = 0u; uint8_t nTPCClustersPi = 0u; uint32_t clusterSizeITSHe3 = 0u; @@ -186,7 +187,7 @@ struct hyperRecoTask { std::vector recoCollisionIds; std::vector isSurvEvSelCollision; std::vector goodCollision; - std::vector isTracked; + std::vector trackedClSize; Preslice perCollision = o2::aod::v0::collisionId; @@ -382,6 +383,7 @@ struct hyperRecoTask { hypCand.clusterSizeITSHe3 = heTrack.itsClusterSizes(); hypCand.nTPCClustersPi = piTrack.tpcNClsFound(); hypCand.tpcSignalPi = piTrack.tpcSignal(); + hypCand.tpcChi2He3 = heTrack.tpcChi2NCl(); hypCand.clusterSizeITSPi = piTrack.itsClusterSizes(); bool heliumPID = heTrack.pidForTracking() == o2::track::PID::Helium3 || heTrack.pidForTracking() == o2::track::PID::Alpha; hypCand.momHe3TPC = (heliumPID && cfgCompensatePIDinTracking) ? heTrack.tpcInnerParam() / 2 : heTrack.tpcInnerParam(); @@ -440,7 +442,7 @@ struct hyperRecoTask { hH3LMassBefSel->Fill(massH3L); hH4LMassBefSel->Fill(massH4L); - if (!isTracked.empty() && isTracked[hypCand.v0ID]) { + if (!trackedClSize.empty() && trackedClSize[hypCand.v0ID] > 0) { hH3LMassTracked->Fill(massH3L); hH4LMassTracked->Fill(massH4L); } @@ -618,10 +620,10 @@ struct hyperRecoTask { void processDataTracked(CollisionsFull const& collisions, aod::V0s const& V0s, aod::TrackedV0s const& tV0s, TracksFull const& tracks, aod::AmbiguousTracks const& ambiTracks, aod::BCsWithTimestamps const& bcs) { - isTracked.clear(); - isTracked.resize(V0s.size(), false); + trackedClSize.clear(); + trackedClSize.resize(V0s.size(), 0); for (const auto& tV0 : tV0s) { - isTracked[tV0.v0Id()] = true; + trackedClSize[tV0.v0Id()] = tV0.itsClsSize(); } processData(collisions, V0s, tracks, ambiTracks, bcs); } @@ -646,8 +648,8 @@ struct hyperRecoTask { hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, - hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, !isTracked.empty() && isTracked[hypCand.v0ID]); + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, + hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, trackedClSize[hypCand.v0ID]); } } PROCESS_SWITCH(hyperRecoTask, processData, "Data analysis", true); @@ -675,8 +677,8 @@ struct hyperRecoTask { hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, - hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, !isTracked.empty() && isTracked[hypCand.v0ID]); + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, + hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, trackedClSize[hypCand.v0ID]); } } PROCESS_SWITCH(hyperRecoTask, processDataWithFlow, "Data analysis with flow", false); @@ -708,8 +710,8 @@ struct hyperRecoTask { hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, - hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, !isTracked.empty() && isTracked[hypCand.v0ID], + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, + hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, trackedClSize[hypCand.v0ID], chargeFactor * hypCand.genPt(), hypCand.genPhi(), hypCand.genEta(), hypCand.genPtHe3(), hypCand.gDecVtx[0], hypCand.gDecVtx[1], hypCand.gDecVtx[2], hypCand.isReco, hypCand.isSignal, hypCand.isRecoMCCollision, hypCand.isSurvEvSelection); @@ -782,7 +784,7 @@ struct hyperRecoTask { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, false, + -1, -1, -1, false, -1, chargeFactor * hypCand.genPt(), hypCand.genPhi(), hypCand.genEta(), hypCand.genPtHe3(), hypCand.gDecVtx[0], hypCand.gDecVtx[1], hypCand.gDecVtx[2], hypCand.isReco, hypCand.isSignal, hypCand.isRecoMCCollision, hypCand.isSurvEvSelection); @@ -792,10 +794,10 @@ struct hyperRecoTask { void processMCTracked(CollisionsFullMC const& collisions, aod::McCollisions const& mcCollisions, aod::V0s const& V0s, aod::TrackedV0s const& tV0s, TracksFull const& tracks, aod::AmbiguousTracks const& ambiTracks, aod::BCsWithTimestamps const& bcs, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) { - isTracked.clear(); - isTracked.resize(V0s.size(), false); + trackedClSize.clear(); + trackedClSize.resize(V0s.size(), 0); for (const auto& tV0 : tV0s) { - isTracked[tV0.v0Id()] = true; + trackedClSize[tV0.v0Id()] = tV0.itsClsSize(); } processMC(collisions, mcCollisions, V0s, tracks, ambiTracks, bcs, trackLabelsMC, particlesMC); } diff --git a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx index 52f038356dc..b4445a5619a 100644 --- a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx +++ b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx @@ -687,14 +687,17 @@ struct hypertriton3bodyFinder { auto Track0Par = getTrackPar(dPtrack); o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); auto Track0dcaXY = dcaInfo[0]; + auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]); auto Track1Par = getTrackPar(dNtrack); o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); auto Track1dcaXY = dcaInfo[0]; + auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]); auto Track2Par = getTrackPar(dBachtrack); o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); auto Track2dcaXY = dcaInfo[0]; + auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]); // H3L DCA Check // auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(), t2.sign()); @@ -712,6 +715,7 @@ struct hypertriton3bodyFinder { p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], fitter3body.getChi2AtPCACandidate(), Track0dcaXY, Track1dcaXY, Track2dcaXY, + Track0dca, Track1dca, Track2dca, 0); // To be fixed } //------------------------------------------------------------------ diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 1e8fdfd22cd..09b2e909ec1 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -91,6 +91,7 @@ struct NucleusCandidate { uint8_t TPCcrossedRows; uint8_t ITSclsMap; uint8_t TPCnCls; + uint8_t TPCnClsShared; uint8_t ITSnCls; uint32_t clusterSizesITS; }; @@ -689,7 +690,7 @@ struct nucleiSpectra { static_cast(track.globalIndex()), static_cast(track.collisionId()), (1 - 2 * iC) * mTrackParCov.getPt(), mTrackParCov.getEta(), mTrackParCov.getPhi(), correctedTpcInnerParam, beta, collision.posZ(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), track.tpcChi2NCl(), nSigmaTPC, tofMasses, fillTree, fillDCAHist, correctPV, isSecondary, fromWeakDecay, flag, track.tpcNClsFindable(), static_cast(track.tpcNClsCrossedRows()), track.itsClusterMap(), - static_cast(track.tpcNClsFound()), static_cast(track.itsNCls()), static_cast(track.itsClusterSizes())}); + static_cast(track.tpcNClsFound()), static_cast(track.tpcNClsShared()), static_cast(track.itsNCls()), static_cast(track.itsClusterSizes())}); } } // end loop over tracks @@ -710,7 +711,7 @@ struct nucleiSpectra { fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { if (c.fillTree) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS); + nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS); } if (c.fillDCAHist) { for (int iS{0}; iS < nuclei::species; ++iS) { @@ -736,7 +737,7 @@ struct nucleiSpectra { fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { if (c.fillTree) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS); + nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS); } if (c.fillDCAHist) { for (int iS{0}; iS < nuclei::species; ++iS) { @@ -765,7 +766,7 @@ struct nucleiSpectra { fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { if (c.fillTree) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS); + nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS); } if (c.fillDCAHist) { for (int iS{0}; iS < nuclei::species; ++iS) { @@ -839,7 +840,7 @@ struct nucleiSpectra { c.flags |= kIsSecondaryFromMaterial; } float absoDecL = computeAbsoDecL(particle); - nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absoDecL); + nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absoDecL); } int index{0}; @@ -860,7 +861,7 @@ struct nucleiSpectra { if (!isReconstructed[index] && (cfgTreeConfig->get(iS, 0u) || cfgTreeConfig->get(iS, 1u))) { float absDecL = computeAbsoDecL(particle); - nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, flags, 0, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absDecL); + nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, flags, 0, 0, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absDecL); } break; } diff --git a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx index 337d87223ad..857a02e1cf2 100644 --- a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx @@ -54,6 +54,7 @@ struct Candidate3body { // 0 - proton, 1 - pion, 2 - bachelor uint8_t dautpcNclusters[3]; uint8_t dauitsclussize[3]; + uint8_t daudcaxytopv[3]; uint8_t daudcatopv[3]; float dautpcNsigma[3]; bool isMatter; @@ -65,6 +66,7 @@ struct Candidate3body { float bachelortofNsigma; TLorentzVector lgencand = {0, 0, 0, 0}; float genct = -1; + float genrapidity = -999; bool isSignal = false; bool isReco = false; int pdgCode = -1; @@ -112,6 +114,7 @@ struct threebodyRecoTask { "registry", { {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, + {"hCentFT0C", "hCentFT0C", {HistType::kTH1F, {{100, 0.0f, 100.0f, "FT0C Centrality"}}}}, {"hCandidatesCounter", "hCandidatesCounter", {HistType::kTH1F, {{12, 0.0f, 12.0f}}}}, {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, @@ -122,6 +125,9 @@ struct threebodyRecoTask { {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, @@ -351,6 +357,8 @@ struct threebodyRecoTask { registry.fill(HIST("hPtProton"), trackProton.pt()); registry.fill(HIST("hPtPionMinus"), trackPion.pt()); registry.fill(HIST("hPtDeuteron"), trackDeuteron.pt()); + registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack0topv()); + registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack1topv()); registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack0topv()); registry.fill(HIST("hDCAPionToPV"), candData.dcatrack1topv()); @@ -379,6 +387,8 @@ struct threebodyRecoTask { registry.fill(HIST("hPtAntiProton"), trackProton.pt()); registry.fill(HIST("hPtPionPlus"), trackPion.pt()); registry.fill(HIST("hPtAntiDeuteron"), trackDeuteron.pt()); + registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack1topv()); + registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack0topv()); registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack1topv()); registry.fill(HIST("hDCAPionToPV"), candData.dcatrack0topv()); @@ -409,10 +419,15 @@ struct threebodyRecoTask { cand3body.dautpcNclusters[0] = trackProton.tpcNClsFound(); cand3body.dautpcNclusters[1] = trackPion.tpcNClsFound(); cand3body.dautpcNclusters[2] = trackDeuteron.tpcNClsFound(); - cand3body.dauitsclussize[0] = trackPion.itsClusterSizes(); + cand3body.dauitsclussize[0] = trackProton.itsClusterSizes(); + cand3body.dauitsclussize[1] = trackPion.itsClusterSizes(); + cand3body.dauitsclussize[2] = trackDeuteron.itsClusterSizes(); cand3body.dautpcNsigma[0] = trackProton.tpcNSigmaPr(); cand3body.dautpcNsigma[1] = trackPion.tpcNSigmaPi(); cand3body.dautpcNsigma[2] = trackDeuteron.tpcNSigmaDe(); + cand3body.daudcaxytopv[0] = cand3body.isMatter ? candData.dcaXYtrack0topv() : candData.dcaXYtrack1topv(); + cand3body.daudcaxytopv[1] = cand3body.isMatter ? candData.dcaXYtrack1topv() : candData.dcaXYtrack0topv(); + cand3body.daudcaxytopv[2] = candData.dcaXYtrack2topv(); cand3body.daudcatopv[0] = cand3body.isMatter ? candData.dcatrack0topv() : candData.dcatrack1topv(); cand3body.daudcatopv[1] = cand3body.isMatter ? candData.dcatrack1topv() : candData.dcatrack0topv(); cand3body.daudcatopv[2] = candData.dcatrack2topv(); @@ -426,6 +441,7 @@ struct threebodyRecoTask { cand3body.mcmotherId = lLabel; cand3body.lgencand = lmother; cand3body.genct = MClifetime; + cand3body.genrapidity = lmother.Rapidity(); cand3body.isSignal = true; cand3body.isReco = true; cand3body.pdgCode = cand3body.isMatter ? motherPdgCode : -motherPdgCode; @@ -514,6 +530,7 @@ struct threebodyRecoTask { return; } registry.fill(HIST("hEventCounter"), 2.5); + registry.fill(HIST("hCentFT0C"), collision.centFT0C()); bool if_hasvtx = false; @@ -537,6 +554,7 @@ struct threebodyRecoTask { cand3body.dautpcNclusters[0], cand3body.dautpcNclusters[1], cand3body.dautpcNclusters[2], cand3body.dauitsclussize[0], cand3body.dauitsclussize[1], cand3body.dauitsclussize[2], cand3body.dautpcNsigma[0], cand3body.dautpcNsigma[1], cand3body.dautpcNsigma[2], cand3body.bachelortofNsigma, + cand3body.daudcaxytopv[0], cand3body.daudcaxytopv[1], cand3body.daudcaxytopv[2], cand3body.daudcatopv[0], cand3body.daudcatopv[1], cand3body.daudcatopv[2]); } } @@ -587,7 +605,7 @@ struct threebodyRecoTask { for (auto& lMother2 : lMCTrack2.mothers_as()) { if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { lLabel = lMother0.globalIndex(); - lPDG = lMother1.pdgCode(); + lPDG = lMother0.pdgCode(); if ((lPDG == motherPdgCode && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == bachelorPdgCode) || (lPDG == -motherPdgCode && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -bachelorPdgCode)) { isTrueCand = true; @@ -620,8 +638,9 @@ struct threebodyRecoTask { cand3body.dautpcNclusters[0], cand3body.dautpcNclusters[1], cand3body.dautpcNclusters[2], cand3body.dauitsclussize[0], cand3body.dauitsclussize[1], cand3body.dauitsclussize[2], cand3body.dautpcNsigma[0], cand3body.dautpcNsigma[1], cand3body.dautpcNsigma[2], cand3body.bachelortofNsigma, + cand3body.daudcaxytopv[0], cand3body.daudcaxytopv[1], cand3body.daudcaxytopv[2], cand3body.daudcatopv[0], cand3body.daudcatopv[1], cand3body.daudcatopv[2], - cand3body.lgencand.P(), cand3body.lgencand.Pt(), cand3body.genct, cand3body.lgencand.Phi(), cand3body.lgencand.Eta(), + cand3body.lgencand.P(), cand3body.lgencand.Pt(), cand3body.genct, cand3body.lgencand.Phi(), cand3body.lgencand.Eta(), cand3body.lgencand.Rapidity(), cand3body.isSignal, cand3body.isReco, cand3body.pdgCode, cand3body.SurvivedEventSelection); } } @@ -653,7 +672,8 @@ struct threebodyRecoTask { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - mcparticle.p(), mcparticle.pt(), MClifetime, mcparticle.phi(), mcparticle.eta(), + -1, -1, -1, + mcparticle.p(), mcparticle.pt(), MClifetime, mcparticle.phi(), mcparticle.eta(), mcparticle.y(), true, false, mcparticle.pdgCode(), isSurEvSelection); } } diff --git a/PWGLF/TableProducer/Strangeness/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/CMakeLists.txt index a4f8061f68d..27aec6b4e62 100644 --- a/PWGLF/TableProducer/Strangeness/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/CMakeLists.txt @@ -56,6 +56,12 @@ o2physics_add_dpl_workflow(hstrangecorrelationfilter PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(double-casc-tree-creator + SOURCES doubleCascTreeCreator.cxx + PUBLIC_LINK_LIBRARIES O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + + o2physics_add_dpl_workflow(lambdakzerobuilder SOURCES lambdakzerobuilder.cxx PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore O2Physics::MLCore diff --git a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt index defa3b1abf9..035c4ca6581 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt @@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(strarawcentsconverter2v4 PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(straevselsconverter + SOURCES straevselsconverter.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(v0coresconverter SOURCES v0coresconverter.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter.cxx new file mode 100644 index 00000000000..9806e15abfc --- /dev/null +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter.cxx @@ -0,0 +1,62 @@ +// 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 "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +using namespace o2; +using namespace o2::framework; + +// Converts Stra Event selections from 000 to 001 +struct straevselsconverter { + Produces straEvSels_001; + + void process(soa::Join const& straEvSels_000_RawCents_004) + { + for (auto& values : straEvSels_000_RawCents_004) { + straEvSels_001(values.sel8(), + values.selection_raw(), + values.multFT0A(), + values.multFT0C(), + values.multFT0A(), + 0 /*dummy FDDA value*/, + 0 /*dummy FDDC value*/, + values.multNTracksPVeta1(), + values.multPVTotalContributors(), + values.multNTracksGlobal(), + values.multNTracksITSTPC(), + values.multAllTracksTPCOnly(), + values.multAllTracksITSTPC(), + values.multZNA(), + values.multZNC(), + values.multZEM1(), + values.multZEM2(), + values.multZPA(), + values.multZPC(), + values.trackOccupancyInTimeRange(), + -1 /*dummy gap side value*/, + -999. /*dummy FT0-A value*/, + -999. /*dummy FT0-C value*/, + -999. /*dummy FV0-A value*/, + -999. /*dummy FDD-A value*/, + -999. /*dummy FDD-C value*/, + -999. /*dummy ZN-A value*/, + -999. /*dummy ZN-C value*/); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Strangeness/doubleCascTreeCreator.cxx b/PWGLF/TableProducer/Strangeness/doubleCascTreeCreator.cxx new file mode 100644 index 00000000000..5ecffca742f --- /dev/null +++ b/PWGLF/TableProducer/Strangeness/doubleCascTreeCreator.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 +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.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 "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/PIDResponse.h" +#include "DCAFitter/DCAFitterN.h" + +#include "PWGLF/DataModel/LFDoubleCascTables.h" +#include "TDatabasePDG.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using Collisions = soa::Join::iterator; +using FullCascades = aod::CascDataExt; +using TracksFull = soa::Join; + +struct doubleCascCand { + float ptCasc1 = -999.f; // signed pt of the cascade + float etaCasc1 = -999.f; + float phiCasc1 = -999.f; + float cascDecLength1 = -999.f; + float omegaMassCasc1 = -999.f; + float xiMassCasc1 = -999.f; + float cosPACasc1 = -999.f; + float dcaBachPVCasc1 = -999.f; + float dcaV0BachCasc1 = -999.f; + float nSigmaKBach1 = -999.f; + + float ptCasc2 = -999.f; + float etaCasc2 = -999.f; + float phiCasc2 = -999.f; + float cascDecLength2 = -999.f; + float omegaMassCasc2 = -999.f; + float xiMassCasc2 = -999.f; + float cosPACasc2 = -999.f; + float dcaBachPVCasc2 = -999.f; + float dcaV0BachCasc2 = -999.f; + float nSigmaKBach2 = -999.f; + float doubleOmegaMass = -999.f; +}; + +struct doubleCascTreeCreator { + Produces doubleCascTable; + std::vector doubleCascCands; + Service ccdb; + o2::vertexing::DCAFitterN<2> fitter; + + int mRunNumber; + + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + + Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Skimmed dataset processing"}; + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + + ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; + ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; + + // binning of (anti)lambda mass QA histograms + ConfigurableAxis massOmegaAxis{"massLambdaAxis", {400, o2::constants::physics::MassOmegaMinus - 0.05f, o2::constants::physics::MassOmegaMinus + 0.035}, "binning for the Omega invariant-mass"}; + ConfigurableAxis massXiAxis{"massXiAxis", {400, o2::constants::physics::MassXiMinus - 0.05f, o2::constants::physics::MassXiMinus + 0.05f}, "binning for the Xi invariant-mass"}; + + Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; + Configurable etaMax{"etaMax", 0.9f, "maximum eta"}; + ConfigurableAxis momAxis{"momAxisFine", {5.e2, 0.f, 5.f}, "momentum axis binning"}; + + Configurable cascPtMin{"cascPtMin", 1.f, "minimum (anti)casc pT (GeV/c)"}; + Configurable cascPtMax{"cascPtMax", 4.f, "maximum (anti)casc pT (GeV/c)"}; + + Configurable minNCrossedRows{"minNCrossedRows", 100, "Minimum number of crossed TPC rows"}; + Configurable minNITSClus{"minNITSClus", 0., "Minimum number of ITS clusters"}; + Configurable minNTPCClus{"minNTPCClus", 100, "Minimum number of TPC clusters"}; + Configurable maxNSharedTPCClus{"maxNSharedTPCClus", 5, "Maximum number of shared TPC clusters"}; + + Configurable minCascCosPA{"minCascCosPA", 0.99f, "Minimum cosine of the pointing angle of the cascade"}; + Configurable nSigmaTPCCut{"nSigmaTPCCut", 3.f, "Number of sigmas for the TPC PID"}; + Configurable dcaBachToPV{"dcaBachToPV", 0.05f, "DCA of the bachelor to the primary vertex"}; + Configurable dcaV0Bach{"dcaV0Bach", 1.f, "DCA between the V0 daughters"}; + Configurable mXiWindow{"mXiWindow", 0.02f, "mXiWindow"}; + Configurable mOmegaWindow{"mOmegaWindow", 0.01f, "mOmegaWindow"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + template + bool selectTrack(T const& track) + { + if (std::abs(track.eta()) > etaMax) { + return false; + } + if (track.itsNCls() < minNITSClus || + track.tpcNClsFound() < minNTPCClus || + track.tpcNClsCrossedRows() < minNCrossedRows || + track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || + track.tpcNClsShared() > maxNSharedTPCClus) { + return false; + } + return true; + } + + template + void initCCDB(Bc const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + auto timestamp = bc.timestamp(); + LOG(info) << "Retrieved GRP for timestamp " << timestamp; + mRunNumber = bc.runNumber(); + if (cfgSkimmedProcessing) { + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), "fDoubleOmega,fOmegaXi"); + zorro.populateHistRegistry(histos, bc.runNumber()); + } + } + + void init(o2::framework::InitContext&) + { + mRunNumber = 0; + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + zorroSummary.setObject(zorro.getZorroSummary()); + + // event QA + histos.add("QA/zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); + histos.add("QA/massXi", ";#it{p}_{T} (GeV/#it{c});#it{M}(#Lambda + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH2F, {momAxis, massXiAxis}); + histos.add("QA/massOmega", ";#it{p}_{T} (GeV/#it{c});#it{M}(#Omega + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH2F, {momAxis, massOmegaAxis}); + } + + template + bool isSelectedCasc(C const& collision, T const&, FullCascades::iterator const& casc) + { + + auto bachelor = casc.bachelor_as(); + auto posDau = casc.posTrack_as(); + auto negDau = casc.negTrack_as(); + + if (!selectTrack(bachelor) || !selectTrack(posDau) || !selectTrack(negDau)) { + return false; + } + if (casc.sign() > 0) { + if (TMath::Abs(posDau.tpcNSigmaPi()) > nSigmaTPCCut || TMath::Abs(negDau.tpcNSigmaPr()) > nSigmaTPCCut) { + return false; + } + } else if (casc.sign() < 0) { + if (TMath::Abs(negDau.tpcNSigmaPi()) > nSigmaTPCCut || TMath::Abs(posDau.tpcNSigmaPr()) > nSigmaTPCCut) { + return false; + } + } + if (TMath::Abs(casc.dcabachtopv()) < dcaBachToPV) { + return false; + } + if (TMath::Abs(casc.dcacascdaughters()) > dcaV0Bach) { + return false; + } + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < minCascCosPA) { + return false; + } + if (TMath::Abs(casc.eta()) > etaMax) { + return false; + } + // mass cuts + bool massInWindow = false; + if (casc.mOmega() > o2::constants::physics::MassOmegaMinus - mOmegaWindow && casc.mOmega() < o2::constants::physics::MassOmegaMinus + mOmegaWindow) { + massInWindow = true; + } + if (casc.mXi() > o2::constants::physics::MassXiMinus - mXiWindow && casc.mXi() < o2::constants::physics::MassXiMinus + mXiWindow) { + massInWindow = true; + } + if (!massInWindow) { + return false; + } + return true; + }; + + template + bool doubleOmegaMass(T const&, FullCascades::iterator const& casc1, FullCascades::iterator const& casc2) + { + // the fake omega decay is the one with the smaller radius + auto& fakeOmega = casc1.cascradius() < casc2.cascradius() ? casc1 : casc2; + auto& realOmega = casc1.cascradius() < casc2.cascradius() ? casc2 : casc1; + auto kaon = fakeOmega.bachelor_as(); + float momKaon[3] = {kaon.px(), kaon.py(), kaon.pz()}; + float momLambda[3] = {fakeOmega.pxlambda(), fakeOmega.pylambda(), fakeOmega.pzlambda()}; + // now compute real Omega-lambda-kaon mass + float momTot[3] = {momKaon[0] + momLambda[0] + realOmega.px(), momKaon[1] + momLambda[1] + realOmega.py(), momKaon[2] + momLambda[2] + realOmega.pz()}; + float eK = std::sqrt(o2::constants::physics::MassKaonCharged * o2::constants::physics::MassKaonCharged + momKaon[0] * momKaon[0] + momKaon[1] * momKaon[1] + momKaon[2] * momKaon[2]); + float eL = std::sqrt(o2::constants::physics::MassLambda0 * o2::constants::physics::MassLambda0 + momLambda[0] * momLambda[0] + momLambda[1] * momLambda[1] + momLambda[2] * momLambda[2]); + float eO = std::sqrt(o2::constants::physics::MassOmegaMinus * o2::constants::physics::MassOmegaMinus + momTot[0] * momTot[0] + momTot[1] * momTot[1] + momTot[2] * momTot[2]); + float eTot = eK + eL + eO; + float mass = std::sqrt(eTot * eTot - momTot[0] * momTot[0] - momTot[1] * momTot[1] - momTot[2] * momTot[2]); + return mass; + } + + template + void fillDoubleCasc(C const& collision, T const& tracks, FullCascades const& cascades) + { + doubleCascCands.clear(); + + for (auto& casc1 : cascades) { + if (!isSelectedCasc(collision, tracks, casc1)) { + continue; + } + for (auto& casc2 : cascades) { + if (!isSelectedCasc(collision, tracks, casc2)) { + continue; + } + + if (casc1.posTrackId() == casc2.posTrackId() || casc1.posTrackId() == casc2.negTrackId() || casc1.bachelorId() == casc2.bachelorId()) { + continue; + } + + auto bach1 = casc1.bachelor_as(); + auto bach2 = casc2.bachelor_as(); + + doubleCascCand cand; + cand.ptCasc1 = casc1.pt(); + cand.etaCasc1 = casc1.eta(); + cand.phiCasc1 = casc1.phi(); + cand.cascDecLength1 = std::hypot(casc1.x() - collision.posX(), casc1.y() - collision.posY(), casc1.z() - collision.posZ()); + cand.omegaMassCasc1 = casc1.mOmega(); + cand.xiMassCasc1 = casc1.mXi(); + cand.cosPACasc1 = casc1.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + cand.dcaBachPVCasc1 = casc1.dcabachtopv(); + cand.dcaV0BachCasc1 = casc1.dcacascdaughters(); + cand.nSigmaKBach1 = bach1.tpcNSigmaKa(); + + cand.ptCasc2 = casc2.pt(); + cand.etaCasc2 = casc2.eta(); + cand.phiCasc2 = casc2.phi(); + cand.cascDecLength2 = std::hypot(casc2.x() - collision.posX(), casc2.y() - collision.posY(), casc2.z() - collision.posZ()); + cand.omegaMassCasc2 = casc2.mOmega(); + cand.xiMassCasc2 = casc2.mXi(); + cand.cosPACasc2 = casc2.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + cand.dcaBachPVCasc2 = casc2.dcabachtopv(); + cand.dcaV0BachCasc2 = casc2.dcacascdaughters(); + cand.nSigmaKBach2 = bach2.tpcNSigmaKa(); + + cand.doubleOmegaMass = doubleOmegaMass(tracks, casc1, casc2); + + doubleCascCands.push_back(cand); + } + } + }; + + void processData(Collisions const& collision, TracksFull const& tracks, FullCascades const& cascades, aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + initCCDB(bc); + + if (!collision.sel8()) + return; + + if (std::abs(collision.posZ()) > zVtxMax) + return; + + if (!collision.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) + return; + + if (cfgSkimmedProcessing) { + zorro.isSelected(collision.bc_as().globalBC()); /// Just let Zorro do the accounting + } + histos.fill(HIST("QA/zVtx"), collision.posZ()); + fillDoubleCasc(collision, tracks, cascades); + + for (auto& cand : doubleCascCands) { + doubleCascTable( + cand.ptCasc1, + cand.etaCasc1, + cand.phiCasc1, + cand.cascDecLength1, + cand.omegaMassCasc1, + cand.xiMassCasc1, + cand.cosPACasc1, + cand.dcaBachPVCasc1, + cand.dcaV0BachCasc1, + cand.nSigmaKBach1, + cand.ptCasc2, + cand.etaCasc2, + cand.phiCasc2, + cand.cascDecLength2, + cand.omegaMassCasc2, + cand.xiMassCasc2, + cand.cosPACasc2, + cand.dcaBachPVCasc2, + cand.dcaV0BachCasc2, + cand.nSigmaKBach2, + cand.doubleOmegaMass); + } + } + PROCESS_SWITCH(doubleCascTreeCreator, processData, "process (Run 3)", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx index 08526c22d5d..c651eb31007 100644 --- a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx @@ -58,6 +58,7 @@ using TracksWithExtra = soa::Join; using FullTracksExtIUTOF = soa::Join; using FullCollisions = soa::Join; +using UDCollisionsFull = soa::Join; // simple bit checkers #define bitset(var, nbit) ((var) |= (1 << (nbit))) @@ -73,8 +74,7 @@ struct strangederivedbuilder { Produces strangeMCColl; // characterises collisions / MC Produces strangeMCMults; // characterises collisions / MC mults Produces strangeCents; // characterises collisions / centrality - Produces strangeRawCents; // characterises collisions / centrality - Produces strangeEvSels; // characterises collisions / sel8 selection + Produces strangeEvSels; // characterises collisions / centrality / sel8 selection Produces strangeStamps; // provides timestamps, run numbers Produces v0collref; // references collisions from V0s Produces casccollref; // references collisions from cascades @@ -167,12 +167,23 @@ struct strangederivedbuilder { Configurable fillRawFT0A{"fillRawFT0A", false, "Fill raw FT0A information for debug"}; Configurable fillRawFT0C{"fillRawFT0C", true, "Fill raw FT0C information for debug"}; Configurable fillRawFV0A{"fillRawFV0A", false, "Fill raw FV0A information for debug"}; + Configurable fillRawFDDA{"fillRawFDDA", false, "Fill raw FDDA information for debug"}; + Configurable fillRawFDDC{"fillRawFDDC", false, "Fill raw FDDC information for debug"}; Configurable fillRawZDC{"fillRawZDC", false, "Fill raw ZDC information for debug"}; Configurable fillRawNTracksEta1{"fillRawNTracksEta1", true, "Fill raw NTracks |eta|<1 information for debug"}; Configurable fillRawNTracksForCorrelation{"fillRawNTracksForCorrelation", true, "Fill raw NTracks for correlation cuts"}; Configurable fillTOFInformation{"fillTOFInformation", true, "Fill Daughter Track TOF information"}; Configurable qaCentrality{"qaCentrality", false, "qa centrality flag: check base raw values"}; + struct : ConfigurableGroup { + ConfigurableAxis axisFT0A{"FT0Aamplitude", {100, 0.0f, 2000.0f}, "FT0Aamplitude"}; + ConfigurableAxis axisFT0C{"FT0Camplitude", {100, 0.0f, 2000.0f}, "FT0Camplitude"}; + ConfigurableAxis axisFV0A{"FV0Aamplitude", {100, 0.0f, 2000.0f}, "FV0Aamplitude"}; + ConfigurableAxis axisFDDA{"FDDAamplitude", {100, 0.0f, 2000.0f}, "FDDAamplitude"}; + ConfigurableAxis axisFDDC{"FDDCamplitude", {100, 0.0f, 2000.0f}, "FDDCamplitude"}; + ConfigurableAxis axisZNA{"ZNAamplitude", {100, 0.0f, 250.0f}, "ZNAamplitude"}; + ConfigurableAxis axisZNC{"ZNCamplitude", {100, 0.0f, 250.0f}, "ZNCamplitude"}; + } axisDetectors; // For manual sliceBy Preslice V0perCollision = o2::aod::v0data::collisionId; @@ -180,6 +191,7 @@ struct strangederivedbuilder { Preslice KFCascperCollision = o2::aod::cascdata::collisionId; Preslice TraCascperCollision = o2::aod::cascdata::collisionId; Preslice mcParticlePerMcCollision = o2::aod::mcparticle::mcCollisionId; + Preslice udCollisionsPerCollision = o2::aod::udcollision::collisionId; std::vector genK0Short; std::vector genLambda; @@ -230,6 +242,14 @@ struct strangederivedbuilder { // for QA and test purposes auto hRawCentrality = histos.add("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality}); + auto hFT0AMultVsFT0AUD = histos.add("hFT0AMultVsFT0AUD", "hFT0AMultVsFT0AUD; FT0-A Mult; FT0-A UD", kTH2F, {axisDetectors.axisFT0A, axisDetectors.axisFT0A}); + auto hFT0CMultVsFT0CUD = histos.add("hFT0CMultVsFT0CUD", "hFT0CMultVsFT0CUD; FT0-C Mult; FT0-C UD", kTH2F, {axisDetectors.axisFT0C, axisDetectors.axisFT0C}); + auto hFV0AMultVsFV0AUD = histos.add("hFV0AMultVsFV0AUD", "hFV0AMultVsFV0AUD; FV0-A Mult; FV0-A UD", kTH2F, {axisDetectors.axisFV0A, axisDetectors.axisFV0A}); + auto hFDDAMultVsFDDAUD = histos.add("hFDDAMultVsFDDAUD", "hFDDAMultVsFDDAUD; FDD-A Mult; FDD-A UD", kTH2F, {axisDetectors.axisFDDA, axisDetectors.axisFDDA}); + auto hFDDCMultVsFDDCUD = histos.add("hFDDCMultVsFDDCUD", "hFDDCMultVsFDDCUD; FDD-C Mult; FDD-C UD", kTH2F, {axisDetectors.axisFDDC, axisDetectors.axisFDDC}); + auto hZNAMultVsZNAUD = histos.add("hZNAMultVsZNAUD", "hZNAMultVsZNAUD; ZNA Mult; ZNA UD", kTH2F, {axisDetectors.axisZNA, axisDetectors.axisZNA}); + auto hZNCMultVsZNCUD = histos.add("hZNCMultVsZNCUD", "hZNCMultVsZNCUD; ZNC Mult; ZNC UD", kTH2F, {axisDetectors.axisZNC, axisDetectors.axisZNC}); + for (int ii = 1; ii < 101; ii++) { float value = 100.5f - static_cast(ii); hRawCentrality->SetBinContent(ii, value); @@ -250,46 +270,76 @@ struct strangederivedbuilder { } } - void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const& /*bcs*/, UDCollisionsFull const& udCollisions) { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisColl = V0s.sliceBy(V0perCollision, collIdx); bool strange = V0Table_thisColl.size() > 0; + + auto bc = collision.bc_as(); + + int gapSide = -1; + float totalFT0AmplitudeA = -999; + float totalFT0AmplitudeC = -999; + float totalFV0AmplitudeA = -999; + float totalFDDAmplitudeA = -999; + float totalFDDAmplitudeC = -999; + float energyCommonZNA = -999; + float energyCommonZNC = -999; + if (udCollisions.size() > 0) { // check that the UD collision table is not empty + auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collIdx); + if (udCollision.size() == 1) { // check that the slicing provide a unique UD collision + for (auto& udColl : udCollision) { + gapSide = udColl.gapSide(); + totalFT0AmplitudeA = udColl.totalFT0AmplitudeA(); + totalFT0AmplitudeC = udColl.totalFT0AmplitudeC(); + totalFV0AmplitudeA = udColl.totalFV0AmplitudeA(); + totalFDDAmplitudeA = udColl.totalFDDAmplitudeA(); + totalFDDAmplitudeC = udColl.totalFDDAmplitudeC(); + energyCommonZNA = udColl.energyCommonZNA(); + energyCommonZNC = udColl.energyCommonZNC(); + } + } + } + // casc table sliced if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centFV0A()); - strangeEvSels(collision.sel8(), collision.selection_raw()); - auto bc = collision.bc_as(); + strangeEvSels(collision.sel8(), collision.selection_raw(), + collision.multFT0A() * static_cast(fillRawFT0A), + collision.multFT0C() * static_cast(fillRawFT0C), + collision.multFV0A() * static_cast(fillRawFV0A), + collision.multFDDA() * static_cast(fillRawFDDA), + collision.multFDDC() * static_cast(fillRawFDDC), + collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), + collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), + collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), + collision.multNTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), + collision.multAllTracksTPCOnly() * static_cast(fillRawNTracksForCorrelation), + collision.multAllTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), + collision.multZNA() * static_cast(fillRawZDC), + collision.multZNC() * static_cast(fillRawZDC), + collision.multZEM1() * static_cast(fillRawZDC), + collision.multZEM2() * static_cast(fillRawZDC), + collision.multZPA() * static_cast(fillRawZDC), + collision.multZPC() * static_cast(fillRawZDC), + collision.trackOccupancyInTimeRange(), + // UPC info + gapSide, + totalFT0AmplitudeA, totalFT0AmplitudeC, totalFV0AmplitudeA, + totalFDDAmplitudeA, totalFDDAmplitudeC, + energyCommonZNA, energyCommonZNC); strangeStamps(bc.runNumber(), bc.timestamp()); - - if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) { - strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), - collision.multFT0C() * static_cast(fillRawFT0C), - collision.multFV0A() * static_cast(fillRawFV0A), - collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), - collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), - collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), - collision.multNTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), - collision.multAllTracksTPCOnly() * static_cast(fillRawNTracksForCorrelation), - collision.multAllTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), - collision.multZNA() * static_cast(fillRawZDC), - collision.multZNC() * static_cast(fillRawZDC), - collision.multZEM1() * static_cast(fillRawZDC), - collision.multZEM2() * static_cast(fillRawZDC), - collision.multZPA() * static_cast(fillRawZDC), - collision.multZPC() * static_cast(fillRawZDC), - collision.trackOccupancyInTimeRange()); - } } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); } } - void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&) + void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const& /*bcs*/, UDCollisionsFull const& udCollisions) { // create collision indices beforehand std::vector V0CollIndices(V0s.size(), -1); // index -1: no collision @@ -314,33 +364,71 @@ struct strangederivedbuilder { CascTable_thisColl.size() > 0 || KFCascTable_thisColl.size() > 0 || TraCascTable_thisColl.size() > 0; + + auto bc = collision.bc_as(); + + int gapSide = -1; + float totalFT0AmplitudeA = -999; + float totalFT0AmplitudeC = -999; + float totalFV0AmplitudeA = -999; + float totalFDDAmplitudeA = -999; + float totalFDDAmplitudeC = -999; + float energyCommonZNA = -999; + float energyCommonZNC = -999; + if (udCollisions.size() > 0) { // check that the UD collision table is not empty + auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collIdx); + if (udCollision.size() == 1) { // check that the slicing provide a unique UD collision + for (auto& udColl : udCollision) { + gapSide = udColl.gapSide(); + totalFT0AmplitudeA = udColl.totalFT0AmplitudeA(); + totalFT0AmplitudeC = udColl.totalFT0AmplitudeC(); + totalFV0AmplitudeA = udColl.totalFV0AmplitudeA(); + totalFDDAmplitudeA = udColl.totalFDDAmplitudeA(); + totalFDDAmplitudeC = udColl.totalFDDAmplitudeC(); + energyCommonZNA = udColl.energyCommonZNA(); + energyCommonZNC = udColl.energyCommonZNC(); + + histos.fill(HIST("hFT0AMultVsFT0AUD"), collision.multFT0A(), udColl.totalFT0AmplitudeA()); + histos.fill(HIST("hFT0CMultVsFT0CUD"), collision.multFT0C(), udColl.totalFT0AmplitudeC()); + histos.fill(HIST("hFV0AMultVsFV0AUD"), collision.multFV0A(), udColl.totalFV0AmplitudeA()); + histos.fill(HIST("hFDDAMultVsFDDAUD"), collision.multFDDA(), udColl.totalFDDAmplitudeA()); + histos.fill(HIST("hFDDCMultVsFDDCUD"), collision.multFDDC(), udColl.totalFDDAmplitudeC()); + histos.fill(HIST("hZNAMultVsZNAUD"), collision.multZNA(), udColl.energyCommonZNA()); + histos.fill(HIST("hZNCMultVsZNCUD"), collision.multZNC(), udColl.energyCommonZNC()); + } + } + } + // casc table sliced if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), centrality, collision.centFV0A()); - strangeEvSels(collision.sel8(), collision.selection_raw()); - auto bc = collision.bc_as(); + strangeEvSels(collision.sel8(), collision.selection_raw(), + collision.multFT0A() * static_cast(fillRawFT0A), + collision.multFT0C() * static_cast(fillRawFT0C), + collision.multFV0A() * static_cast(fillRawFV0A), + collision.multFDDA() * static_cast(fillRawFDDA), + collision.multFDDC() * static_cast(fillRawFDDC), + collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), + collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), + collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), + collision.multNTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), + collision.multAllTracksTPCOnly() * static_cast(fillRawNTracksForCorrelation), + collision.multAllTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), + collision.multZNA() * static_cast(fillRawZDC), + collision.multZNC() * static_cast(fillRawZDC), + collision.multZEM1() * static_cast(fillRawZDC), + collision.multZEM2() * static_cast(fillRawZDC), + collision.multZPA() * static_cast(fillRawZDC), + collision.multZPC() * static_cast(fillRawZDC), + collision.trackOccupancyInTimeRange(), + // UPC info + gapSide, + totalFT0AmplitudeA, totalFT0AmplitudeC, totalFV0AmplitudeA, + totalFDDAmplitudeA, totalFDDAmplitudeC, + energyCommonZNA, energyCommonZNC); strangeStamps(bc.runNumber(), bc.timestamp()); - - if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) { - strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), - collision.multFT0C() * static_cast(fillRawFT0C), - collision.multFV0A() * static_cast(fillRawFV0A), - collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), - collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), - collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), - collision.multNTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), - collision.multAllTracksTPCOnly() * static_cast(fillRawNTracksForCorrelation), - collision.multAllTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), - collision.multZNA() * static_cast(fillRawZDC), - collision.multZNC() * static_cast(fillRawZDC), - collision.multZEM1() * static_cast(fillRawZDC), - collision.multZEM2() * static_cast(fillRawZDC), - collision.multZPA() * static_cast(fillRawZDC), - collision.multZPC() * static_cast(fillRawZDC), - collision.trackOccupancyInTimeRange()); - } } for (const auto& v0 : V0Table_thisColl) @@ -364,7 +452,7 @@ struct strangederivedbuilder { tracasccollref(TraCascadeCollIndices[casc.globalIndex()]); } - void processCollisionsMC(soa::Join const& collisions, soa::Join const& V0s, soa::Join const& /*V0MCCores*/, soa::Join const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&, soa::Join const& mcCollisions, aod::McParticles const&) + void processCollisionsMC(soa::Join const& collisions, soa::Join const& V0s, soa::Join const& /*V0MCCores*/, soa::Join const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const& /*bcs*/, UDCollisionsFull const& udCollisions, soa::Join const& mcCollisions, aod::McParticles const&) { // create collision indices beforehand std::vector V0CollIndices(V0s.size(), -1); // index -1: no collision @@ -402,34 +490,72 @@ struct strangederivedbuilder { CascTable_thisColl.size() > 0 || KFCascTable_thisColl.size() > 0 || TraCascTable_thisColl.size() > 0; + + auto bc = collision.bc_as(); + + int gapSide = -1; + float totalFT0AmplitudeA = -999; + float totalFT0AmplitudeC = -999; + float totalFV0AmplitudeA = -999; + float totalFDDAmplitudeA = -999; + float totalFDDAmplitudeC = -999; + float energyCommonZNA = -999; + float energyCommonZNC = -999; + if (udCollisions.size() > 0) { // check that the UD collision table is not empty + auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collIdx); + if (udCollision.size() == 1) { // check that the slicing provide a unique UD collision + for (auto& udColl : udCollision) { + gapSide = udColl.gapSide(); + totalFT0AmplitudeA = udColl.totalFT0AmplitudeA(); + totalFT0AmplitudeC = udColl.totalFT0AmplitudeC(); + totalFV0AmplitudeA = udColl.totalFV0AmplitudeA(); + totalFDDAmplitudeA = udColl.totalFDDAmplitudeA(); + totalFDDAmplitudeC = udColl.totalFDDAmplitudeC(); + energyCommonZNA = udColl.energyCommonZNA(); + energyCommonZNC = udColl.energyCommonZNC(); + + histos.fill(HIST("hFT0AMultVsFT0AUD"), collision.multFT0A(), udColl.totalFT0AmplitudeA()); + histos.fill(HIST("hFT0CMultVsFT0CUD"), collision.multFT0C(), udColl.totalFT0AmplitudeC()); + histos.fill(HIST("hFV0AMultVsFV0AUD"), collision.multFV0A(), udColl.totalFV0AmplitudeA()); + histos.fill(HIST("hFDDAMultVsFDDAUD"), collision.multFDDA(), udColl.totalFDDAmplitudeA()); + histos.fill(HIST("hFDDCMultVsFDDCUD"), collision.multFDDC(), udColl.totalFDDAmplitudeC()); + histos.fill(HIST("hZNAMultVsZNAUD"), collision.multZNA(), udColl.energyCommonZNA()); + histos.fill(HIST("hZNCMultVsZNCUD"), collision.multZNC(), udColl.energyCommonZNC()); + } + } + } + // casc table sliced if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCollLabels(collision.mcCollisionId()); strangeCents(collision.centFT0M(), collision.centFT0A(), centrality, collision.centFV0A()); - strangeEvSels(collision.sel8(), collision.selection_raw()); - auto bc = collision.bc_as(); + strangeEvSels(collision.sel8(), collision.selection_raw(), + collision.multFT0A() * static_cast(fillRawFT0A), + collision.multFT0C() * static_cast(fillRawFT0C), + collision.multFV0A() * static_cast(fillRawFV0A), + collision.multFDDA() * static_cast(fillRawFDDA), + collision.multFDDC() * static_cast(fillRawFDDC), + collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), + collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), + collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), + collision.multNTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), + collision.multAllTracksTPCOnly() * static_cast(fillRawNTracksForCorrelation), + collision.multAllTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), + collision.multZNA() * static_cast(fillRawZDC), + collision.multZNC() * static_cast(fillRawZDC), + collision.multZEM1() * static_cast(fillRawZDC), + collision.multZEM2() * static_cast(fillRawZDC), + collision.multZPA() * static_cast(fillRawZDC), + collision.multZPC() * static_cast(fillRawZDC), + collision.trackOccupancyInTimeRange(), + // UPC info + gapSide, + totalFT0AmplitudeA, totalFT0AmplitudeC, totalFV0AmplitudeA, + totalFDDAmplitudeA, totalFDDAmplitudeC, + energyCommonZNA, energyCommonZNC); strangeStamps(bc.runNumber(), bc.timestamp()); - - if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) { - strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), - collision.multFT0C() * static_cast(fillRawFT0C), - collision.multFV0A() * static_cast(fillRawFV0A), - collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), - collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), - collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), - collision.multNTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), - collision.multAllTracksTPCOnly() * static_cast(fillRawNTracksForCorrelation), - collision.multAllTracksITSTPC() * static_cast(fillRawNTracksForCorrelation), - collision.multZNA() * static_cast(fillRawZDC), - collision.multZNC() * static_cast(fillRawZDC), - collision.multZEM1() * static_cast(fillRawZDC), - collision.multZEM2() * static_cast(fillRawZDC), - collision.multZPA() * static_cast(fillRawZDC), - collision.multZPC() * static_cast(fillRawZDC), - collision.trackOccupancyInTimeRange()); - } } for (const auto& v0 : V0Table_thisColl) V0CollIndices[v0.globalIndex()] = strangeColl.lastIndex(); @@ -470,7 +596,7 @@ struct strangederivedbuilder { // Figure out the numbering of the new tracks table // assume filling per order int nTracks = 0; - for (int i = 0; i < int(trackMap.size()); i++) { + for (int i = 0; i < static_cast(trackMap.size()); i++) { if (trackMap[i] >= 0) { trackMap[i] = nTracks++; } @@ -545,7 +671,7 @@ struct strangederivedbuilder { // Figure out the numbering of the new tracks table // assume filling per order int nTracks = 0; - for (int i = 0; i < int(trackMap.size()); i++) { + for (int i = 0; i < static_cast(trackMap.size()); i++) { if (trackMap[i] >= 0) { trackMap[i] = nTracks++; } @@ -637,7 +763,7 @@ struct strangederivedbuilder { // Figure out the numbering of the new mcMother table // assume filling per order int nParticles = 0; - for (int i = 0; i < int(motherReference.size()); i++) { + for (int i = 0; i < static_cast(motherReference.size()); i++) { if (motherReference[i] >= 0) { motherReference[i] = nParticles++; // count particles of interest } @@ -829,7 +955,7 @@ struct strangederivedbuilder { uint64_t combineProngIndices(uint32_t low, uint32_t high) { - return (((uint64_t)high) << 32) | ((uint64_t)low); + return ((static_cast(high)) << 32) | (static_cast(low)); } void processV0FoundTags(aod::V0s const& foundV0s, aod::V0Datas const& findableV0s, aod::FindableV0s const& /* added to avoid troubles */) @@ -851,7 +977,7 @@ struct strangederivedbuilder { using uint128_t = __uint128_t; uint128_t combineProngIndices128(uint32_t pos, uint32_t neg, uint32_t bach) { - return (((uint128_t)pos) << 64) | (((uint128_t)neg) << 32) | ((uint128_t)bach); + return ((static_cast(pos)) << 64) | ((static_cast(neg)) << 32) | (static_cast(bach)); } void processCascFoundTags(aod::Cascades const& foundCascades, aod::CascDatas const& findableCascades, aod::V0s const&, aod::FindableCascades const& /* added to avoid troubles */) diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx index 8928c5e2470..ba415978df2 100644 --- a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx +++ b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx @@ -62,6 +62,9 @@ struct hypertriton3bodyQa { {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, @@ -103,6 +106,8 @@ struct hypertriton3bodyQa { registry.fill(HIST("hPtProton"), track0.pt()); registry.fill(HIST("hPtPionMinus"), track1.pt()); registry.fill(HIST("hPtDeuteron"), track2.pt()); + registry.fill(HIST("hDCAXYProtonToPV"), vtx.dcaXYtrack0topv()); + registry.fill(HIST("hDCAXYPionToPV"), vtx.dcaXYtrack1topv()); registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv()); registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv()); registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows()); @@ -111,11 +116,14 @@ struct hypertriton3bodyQa { registry.fill(HIST("hPtPionPlus"), track0.pt()); registry.fill(HIST("hPtAntiProton"), track1.pt()); registry.fill(HIST("hPtAntiDeuteron"), track2.pt()); + registry.fill(HIST("hDCAXYProtonToPV"), vtx.dcaXYtrack1topv()); + registry.fill(HIST("hDCAXYPionToPV"), vtx.dcaXYtrack0topv()); registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv()); registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv()); registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows()); registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows()); } + registry.fill(HIST("hDCAXYDeuteronToPV"), vtx.dcaXYtrack2topv()); registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); } @@ -165,6 +173,9 @@ struct hypertriton3bodyAnalysis { {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, + {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, @@ -371,6 +382,8 @@ struct hypertriton3bodyAnalysis { registry.fill(HIST("hPtProton"), trackProton.pt()); registry.fill(HIST("hPtPionMinus"), trackPion.pt()); registry.fill(HIST("hPtDeuteron"), trackDeuteron.pt()); + registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack0topv()); + registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack1topv()); registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack0topv()); registry.fill(HIST("hDCAPionToPV"), candData.dcatrack1topv()); @@ -392,6 +405,8 @@ struct hypertriton3bodyAnalysis { registry.fill(HIST("hPtAntiProton"), trackProton.pt()); registry.fill(HIST("hPtPionPlus"), trackPion.pt()); registry.fill(HIST("hPtAntiDeuteron"), trackDeuteron.pt()); + registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack1topv()); + registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack0topv()); registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack1topv()); registry.fill(HIST("hDCAPionToPV"), candData.dcatrack0topv()); @@ -408,6 +423,7 @@ struct hypertriton3bodyAnalysis { } else { return; } + registry.fill(HIST("hDCAXYDeuteronToPV"), candData.dcaXYtrack2topv()); registry.fill(HIST("hDCADeuteronToPV"), candData.dcatrack2topv()); registry.fill(HIST("hVtxCosPA"), candData.vtxcosPA(dCollision.posX(), dCollision.posY(), dCollision.posZ())); registry.fill(HIST("hDCAVtxDau"), candData.dcaVtxdaughters()); diff --git a/PWGLF/Tasks/Resonances/KshortKshort.cxx b/PWGLF/Tasks/Resonances/KshortKshort.cxx index 4614cb2f4c9..3fbe2da0bc7 100644 --- a/PWGLF/Tasks/Resonances/KshortKshort.cxx +++ b/PWGLF/Tasks/Resonances/KshortKshort.cxx @@ -68,6 +68,8 @@ struct strangeness_tutorial { Configurable correlation2Dhist{"correlation2Dhist", true, "Lamda K0 mass correlation"}; Configurable DCAv0topv{"DCAv0topv", false, "DCA V0 to PV"}; Configurable armcut{"armcut", true, "arm cut"}; + Configurable globalTracks{"globalTracks", false, "Global tracks"}; + Configurable hasTPC{"hasTPC", false, "TPC"}; // Configurable for event selection Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; @@ -285,26 +287,27 @@ struct strangeness_tutorial { return false; } hglue.fill(HIST("heventscheck"), 2.5); + if (!collision.sel8()) { return false; } hglue.fill(HIST("heventscheck"), 3.5); + if (piluprejection && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { return false; } hglue.fill(HIST("heventscheck"), 4.5); + if (goodzvertex && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; } hglue.fill(HIST("heventscheck"), 5.5); + if (itstpctracks && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { return false; } hglue.fill(HIST("heventscheck"), 6.5); - // if (collision.alias_bit(kTVXinTRD)) { - // // TRD triggered - // // return 0; - // } + auto multNTracksPV = collision.multNTracksPV(); if (additionalEvsel && multNTracksPV < fMultPVCutLow->Eval(multiplicity)) { return false; @@ -314,12 +317,7 @@ struct strangeness_tutorial { return false; } hglue.fill(HIST("heventscheck"), 8.5); - // if (multTrk < fMultCutLow->Eval(multiplicity)) - // return 0; - // if (multTrk > fMultCutHigh->Eval(multiplicity)) - // return 0; - // if (multTrk > fMultMultPVCut->Eval(multNTracksPV)) - // return 0; + return true; } @@ -368,7 +366,6 @@ struct strangeness_tutorial { if (DCAv0topv && fabs(candidate.dcav0topv()) > cMaxV0DCA) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 1.5); if (correlation2Dhist) rKzeroShort.fill(HIST("mass_lambda_kshort_after1"), candidate.mK0Short(), candidate.mLambda()); @@ -376,13 +373,9 @@ struct strangeness_tutorial { if (rapidityks && TMath::Abs(candidate.yK0Short()) >= ConfKsrapidity) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 2.5); - rKzeroShort.fill(HIST("mass_lambda_kshort_after2"), candidate.mK0Short(), candidate.mLambda()); - - // if (isStandarv0 && candidate.isStandardV0 == 0) { - // return false; - // } + if (correlation2Dhist) + rKzeroShort.fill(HIST("mass_lambda_kshort_after2"), candidate.mK0Short(), candidate.mLambda()); if (pT < ConfV0PtMin) { return false; @@ -454,65 +447,60 @@ struct strangeness_tutorial { template bool isSelectedV0Daughter(T const& track, float charge, double nsigmaV0Daughter, V0s const& /*candidate*/) { - // if (QAv0_daughters) { - // (charge == -1) ? rKzeroShort.fill(HIST("negative_pt"), track.pt()) : rKzeroShort.fill(HIST("positive_pt"), track.pt()); - // (charge == -1) ? rKzeroShort.fill(HIST("negative_eta"), track.eta()) : rKzeroShort.fill(HIST("positive_eta"), track.eta()); - // (charge == -1) ? rKzeroShort.fill(HIST("negative_phi"), track.phi()) : rKzeroShort.fill(HIST("positive_phi"), track.phi()); - // } if (QAPID) { // Filling the PID of the V0 daughters in the region of the K0 peak. - // tpcInnerParam is the momentum at the inner wall of TPC. So momentum of tpc vs nsigma of tpc is plotted. - // if (0.45 < candidate.mK0Short() && candidate.mK0Short() < 0.55) { - // } (charge == 1) ? rKzeroShort.fill(HIST("hNSigmaPosPionK0s_before"), track.tpcInnerParam(), track.tpcNSigmaPi()) : rKzeroShort.fill(HIST("hNSigmaNegPionK0s_before"), track.tpcInnerParam(), track.tpcNSigmaPi()); rKzeroShort.fill(HIST("dE_by_dx_TPC"), track.p(), track.tpcSignal()); } const auto eta = track.eta(); const auto tpcNClsF = track.tpcNClsFound(); - // const auto dcaXY = track.dcaXY(); // for this we need TrackDCA table const auto sign = track.sign(); + hglue.fill(HIST("htrackscheck_v0_daughters"), 0.5); - if (!track.hasTPC()) + + if (hasTPC && !track.hasTPC()) return false; hglue.fill(HIST("htrackscheck_v0_daughters"), 1.5); - if (track.tpcNClsCrossedRows() < tpcCrossedrows) - return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 2.5); - if (track.tpcCrossedRowsOverFindableCls() < tpcCrossedrowsOverfcls) - return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 3.5); - if (charge < 0 && sign > 0) { - return false; + if (!globalTracks) { + if (track.tpcNClsCrossedRows() < tpcCrossedrows) + return false; + hglue.fill(HIST("htrackscheck_v0_daughters"), 2.5); + + if (track.tpcCrossedRowsOverFindableCls() < tpcCrossedrowsOverfcls) + return false; + hglue.fill(HIST("htrackscheck_v0_daughters"), 3.5); + + if (tpcNClsF < ConfDaughTPCnclsMin) { + return false; + } + hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); + } else { + if (!track.isGlobalTrack()) + return false; + hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); } - hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); - if (charge > 0 && sign < 0) { + + if (charge < 0 && sign > 0) { return false; } hglue.fill(HIST("htrackscheck_v0_daughters"), 5.5); - if (std::abs(eta) > ConfDaughEta) { + + if (charge > 0 && sign < 0) { return false; } hglue.fill(HIST("htrackscheck_v0_daughters"), 6.5); - if (tpcNClsF < ConfDaughTPCnclsMin) { + + if (std::abs(eta) > ConfDaughEta) { return false; } hglue.fill(HIST("htrackscheck_v0_daughters"), 7.5); - // if (std::abs(dcaXY) < ConfDaughDCAMin) { - // return false; - // } - // v0 PID selection + if (std::abs(nsigmaV0Daughter) > ConfDaughPIDCuts) { return false; } hglue.fill(HIST("htrackscheck_v0_daughters"), 8.5); - // if (QAPID) { - // // if (0.45 < candidate.mK0Short() && candidate.mK0Short() < 0.55) { - // (charge == 1) ? rKzeroShort.fill(HIST("hNSigmaPosPionK0s_after"), track.tpcInnerParam(), track.tpcNSigmaPi()) : rKzeroShort.fill(HIST("hNSigmaNegPionK0s_after"), track.tpcInnerParam(), track.tpcNSigmaPi()); - // // } - // } - return true; } diff --git a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx index 012da260c95..861f820e157 100644 --- a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx @@ -633,7 +633,7 @@ struct derivedCascadeAnalysis { return true; } - void processCascades(soa::Join::iterator const& coll, soa::Join const& Cascades, soa::Join const&) + void processCascades(soa::Join::iterator const& coll, soa::Join const& Cascades, soa::Join const&) { if (!IsEventAccepted(coll, coll.sel8())) @@ -907,7 +907,7 @@ struct derivedCascadeAnalysis { } } } - void processCascadesMCrec(soa::Join::iterator const& coll, soa::Join const& Cascades, soa::Join const&) + void processCascadesMCrec(soa::Join::iterator const& coll, soa::Join const& Cascades, soa::Join const&) { if (!IsEventAccepted(coll, coll.sel8())) return; diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx index 0c163e41a9f..606fca84348 100644 --- a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx @@ -49,6 +49,7 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" +#include "PWGUD/Core/SGSelector.h" using namespace o2; using namespace o2::framework; @@ -161,6 +162,19 @@ struct derivedlambdakzeroanalysis { ConfigurableAxis axisTPCsignal{"axisTPCsignal", {200, 0.0f, 200.0f}, "TPC signal"}; ConfigurableAxis axisTOFdeltaT{"axisTOFdeltaT", {200, -5000.0f, 5000.0f}, "TOF Delta T (ps)"}; + // UPC axes + ConfigurableAxis axisSelGap{"axisSelGap", {4, -1.5, 2.5}, "Gap side"}; + + // UPC selections + SGSelector sgSelector; + struct : ConfigurableGroup { + Configurable FV0cut{"FV0cut", 100., "FV0A threshold"}; + Configurable FT0Acut{"FT0Acut", 200., "FT0A threshold"}; + Configurable FT0Ccut{"FT0Ccut", 100., "FT0C threshold"}; + Configurable ZDCcut{"ZDCcut", 10., "ZDC threshold"}; + // Configurable gapSel{"gapSel", 2, "Gap selection"}; + } upcCuts; + // 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"}; @@ -177,8 +191,8 @@ struct derivedlambdakzeroanalysis { ConfigurableAxis axisMonteCarloNch{"axisMonteCarloNch", {300, 0.0f, 3000.0f}, "N_{ch} MC"}; // For manual sliceBy - // Preslice> perMcCollision = aod::v0data::straMCCollisionId; - PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; + // Preslice> perMcCollision = aod::v0data::straMCCollisionId; + PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; enum selection : uint64_t { selCosPA = 0, selRadius, @@ -289,9 +303,9 @@ struct derivedlambdakzeroanalysis { // TOF PID if (TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaNegativePionK0Short) | (uint64_t(1) << selTOFDeltaTNegativePionK0Short); - if (TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda); if (TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda); + if (TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativeProtonLambda) | (uint64_t(1) << selTOFDeltaTNegativeProtonLambda); } @@ -333,6 +347,9 @@ struct derivedlambdakzeroanalysis { histos.add("hEventOccupancy", "hEventOccupancy", kTH1F, {axisOccupancy}); histos.add("hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH2F, {axisCentrality, axisOccupancy}); + histos.add("hGapSide", "Gap side; Entries", kTH1F, {{5, -0.5, 4.5}}); + histos.add("hSelGapSide", "Selected gap side; Entries", kTH1F, {axisSelGap}); + // for QA and test purposes auto hRawCentrality = histos.add("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality}); @@ -344,6 +361,12 @@ struct derivedlambdakzeroanalysis { // histograms versus mass if (analyseK0Short) { histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + // Non-UPC info + histos.add("h3dMassK0ShortHadronic", "h3dMassK0ShortHadronic", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + // UPC info + histos.add("h3dMassK0ShortSGA", "h3dMassK0ShortSGA", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + histos.add("h3dMassK0ShortSGC", "h3dMassK0ShortSGC", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + histos.add("h3dMassK0ShortDG", "h3dMassK0ShortDG", kTH3F, {axisCentrality, axisPt, axisK0Mass}); if (doTPCQA) { histos.add("K0Short/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC}); histos.add("K0Short/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC}); @@ -383,6 +406,12 @@ struct derivedlambdakzeroanalysis { } if (analyseLambda) { histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + // Non-UPC info + histos.add("h3dMassLambdaHadronic", "h3dMassLambdaHadronic", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + // UPC info + histos.add("h3dMassLambdaSGA", "h3dMassLambdaSGA", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add("h3dMassLambdaSGC", "h3dMassLambdaSGC", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add("h3dMassLambdaDG", "h3dMassLambdaDG", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); if (doTPCQA) { histos.add("Lambda/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC}); histos.add("Lambda/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC}); @@ -422,6 +451,12 @@ struct derivedlambdakzeroanalysis { } if (analyseAntiLambda) { histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + // Non-UPC info + histos.add("h3dMassAntiLambdaHadronic", "h3dMassAntiLambdaHadronic", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + // UPC info + histos.add("h3dMassAntiLambdaSGA", "h3dMassAntiLambdaSGA", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add("h3dMassAntiLambdaSGC", "h3dMassAntiLambdaSGC", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add("h3dMassAntiLambdaDG", "h3dMassAntiLambdaDG", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); if (doTPCQA) { histos.add("AntiLambda/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC}); histos.add("AntiLambda/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC}); @@ -822,7 +857,7 @@ struct derivedlambdakzeroanalysis { } template - void analyseCandidate(TV0 v0, float pt, float centrality, uint64_t selMap) + void analyseCandidate(TV0 v0, float pt, float centrality, uint64_t selMap, uint8_t gapSide) // precalculate this information so that a check is one mask operation, not many { auto posTrackExtra = v0.template posTrackExtra_as(); @@ -853,6 +888,14 @@ struct derivedlambdakzeroanalysis { if (verifyMask(selMap, maskSelectionK0Short) && analyseK0Short) { histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), v0.alpha(), v0.qtarm()); // cross-check histos.fill(HIST("h3dMassK0Short"), centrality, pt, v0.mK0Short()); + if (gapSide == 0) + histos.fill(HIST("h3dMassK0ShortSGA"), centrality, pt, v0.mK0Short()); + if (gapSide == 1) + histos.fill(HIST("h3dMassK0ShortSGC"), centrality, pt, v0.mK0Short()); + if (gapSide == 2) + histos.fill(HIST("h3dMassK0ShortDG"), centrality, pt, v0.mK0Short()); + if (gapSide > 2) + histos.fill(HIST("h3dMassK0ShortHadronic"), centrality, pt, v0.mK0Short()); histos.fill(HIST("hMassK0Short"), v0.mK0Short()); if (doPlainTopoQA) { histos.fill(HIST("K0Short/hPosDCAToPV"), v0.dcapostopv()); @@ -898,6 +941,14 @@ struct derivedlambdakzeroanalysis { } if (verifyMask(selMap, maskSelectionLambda) && analyseLambda) { histos.fill(HIST("h3dMassLambda"), centrality, pt, v0.mLambda()); + if (gapSide == 0) + histos.fill(HIST("h3dMassLambdaSGA"), centrality, pt, v0.mLambda()); + if (gapSide == 1) + histos.fill(HIST("h3dMassLambdaSGC"), centrality, pt, v0.mLambda()); + if (gapSide == 2) + histos.fill(HIST("h3dMassLambdaDG"), centrality, pt, v0.mLambda()); + if (gapSide > 2) + histos.fill(HIST("h3dMassLambdaHadronic"), centrality, pt, v0.mLambda()); if (doPlainTopoQA) { histos.fill(HIST("Lambda/hPosDCAToPV"), v0.dcapostopv()); histos.fill(HIST("Lambda/hNegDCAToPV"), v0.dcanegtopv()); @@ -942,6 +993,14 @@ struct derivedlambdakzeroanalysis { } if (verifyMask(selMap, maskSelectionAntiLambda) && analyseAntiLambda) { histos.fill(HIST("h3dMassAntiLambda"), centrality, pt, v0.mAntiLambda()); + if (gapSide == 0) + histos.fill(HIST("h3dMassAntiLambdaSGA"), centrality, pt, v0.mAntiLambda()); + if (gapSide == 1) + histos.fill(HIST("h3dMassAntiLambdaSGC"), centrality, pt, v0.mAntiLambda()); + if (gapSide == 2) + histos.fill(HIST("h3dMassAntiLambdaDG"), centrality, pt, v0.mAntiLambda()); + if (gapSide > 2) + histos.fill(HIST("h3dMassAntiLambdaHadronic"), centrality, pt, v0.mAntiLambda()); if (doPlainTopoQA) { histos.fill(HIST("AntiLambda/hPosDCAToPV"), v0.dcapostopv()); histos.fill(HIST("AntiLambda/hNegDCAToPV"), v0.dcanegtopv()); @@ -1077,7 +1136,7 @@ struct derivedlambdakzeroanalysis { // ______________________________________________________ // Real data processing - no MC subscription - void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) + void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) { histos.fill(HIST("hEventSelection"), 0. /* all collisions */); if (!collision.sel8()) { @@ -1150,6 +1209,17 @@ struct derivedlambdakzeroanalysis { centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); } + // gap side + int gapSide = collision.gapSide(); + int selGapSide = -1; + // -1 --> Hadronic + // 0 --> Single Gap - A side + // 1 --> Single Gap - C side + // 2 --> Double Gap - both A & C sides + selGapSide = sgSelector.trueGap(collision, upcCuts.FV0cut, upcCuts.FT0Acut, upcCuts.FT0Ccut, upcCuts.ZDCcut); + histos.fill(HIST("hGapSide"), gapSide); + histos.fill(HIST("hSelGapSide"), selGapSide); + histos.fill(HIST("hEventCentrality"), centrality); histos.fill(HIST("hCentralityVsNch"), centrality, collision.multNTracksPVeta1()); @@ -1175,13 +1245,13 @@ struct derivedlambdakzeroanalysis { selMap = selMap | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selConsiderAntiLambda); selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda); - analyseCandidate(v0, v0.pt(), centrality, selMap); + analyseCandidate(v0, v0.pt(), centrality, selMap, selGapSide); } // end v0 loop } // ______________________________________________________ // Simulated processing (subscribes to MC information too) - void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&) + void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&) { histos.fill(HIST("hEventSelection"), 0. /* all collisions */); if (!collision.sel8()) { @@ -1254,6 +1324,17 @@ struct derivedlambdakzeroanalysis { centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); } + // gap side + int gapSide = collision.gapSide(); + int selGapSide = -1; + // -1 --> Hadronic + // 0 --> Single Gap - A side + // 1 --> Single Gap - C side + // 2 --> Double Gap - both A & C sides + selGapSide = sgSelector.trueGap(collision, upcCuts.FV0cut, upcCuts.FT0Acut, upcCuts.FT0Ccut, upcCuts.ZDCcut); + histos.fill(HIST("hGapSide"), gapSide); + histos.fill(HIST("hSelGapSide"), selGapSide); + histos.fill(HIST("hEventCentrality"), centrality); histos.fill(HIST("hCentralityVsNch"), centrality, collision.multNTracksPVeta1()); @@ -1295,7 +1376,7 @@ struct derivedlambdakzeroanalysis { selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda); } - analyseCandidate(v0, ptmc, centrality, selMap); + analyseCandidate(v0, ptmc, centrality, selMap, selGapSide); if (doCollisionAssociationQA) { // check collision association explicitly @@ -1314,7 +1395,7 @@ struct derivedlambdakzeroanalysis { // ______________________________________________________ // Simulated processing (subscribes to MC information too) - void processGenerated(soa::Join const& mcCollisions, soa::Join const& V0MCCores, soa::Join const& CascMCCores, soa::Join const& collisions) + void processGenerated(soa::Join const& mcCollisions, soa::Join const& V0MCCores, soa::Join const& CascMCCores, soa::Join const& collisions) { std::vector listBestCollisionIdx = fillGenEventHist(mcCollisions, collisions); for (auto const& v0MC : V0MCCores) { @@ -1401,7 +1482,7 @@ struct derivedlambdakzeroanalysis { // ______________________________________________________ // Simulated processing // Fill event information (for event loss estimation) and return the index to the recoed collision associated to a given MC collision. - std::vector fillGenEventHist(soa::Join const& mcCollisions, soa::Join const& collisions) + std::vector fillGenEventHist(soa::Join const& mcCollisions, soa::Join const& collisions) { std::vector listBestCollisionIdx(mcCollisions.size()); for (auto const& mcCollision : mcCollisions) { @@ -1497,49 +1578,49 @@ struct derivedlambdakzeroanalysis { auto hOmegaMinus = histos.get(HIST("h2dGeneratedOmegaMinus")); auto hOmegaPlus = histos.get(HIST("h2dGeneratedOmegaPlus")); for (auto& gVec : geK0Short) { - if (int(gVec.generatedK0Short().size()) != hK0Short->GetNcells()) + if (static_cast(gVec.generatedK0Short().size()) != hK0Short->GetNcells()) LOGF(fatal, "K0Short: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedK0Short().size(), hK0Short->GetNcells()); for (int iv = 0; iv < hK0Short->GetNcells(); iv++) { hK0Short->SetBinContent(iv, hK0Short->GetBinContent(iv) + gVec.generatedK0Short()[iv]); } } for (auto& gVec : geLambda) { - if (int(gVec.generatedLambda().size()) != hLambda->GetNcells()) + if (static_cast(gVec.generatedLambda().size()) != hLambda->GetNcells()) LOGF(fatal, "Lambda: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedLambda().size(), hLambda->GetNcells()); for (int iv = 0; iv < hLambda->GetNcells(); iv++) { hLambda->SetBinContent(iv, hLambda->GetBinContent(iv) + gVec.generatedLambda()[iv]); } } for (auto& gVec : geAntiLambda) { - if (int(gVec.generatedAntiLambda().size()) != hAntiLambda->GetNcells()) + if (static_cast(gVec.generatedAntiLambda().size()) != hAntiLambda->GetNcells()) LOGF(fatal, "AntiLambda: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedAntiLambda().size(), hAntiLambda->GetNcells()); for (int iv = 0; iv < hAntiLambda->GetNcells(); iv++) { hAntiLambda->SetBinContent(iv, hAntiLambda->GetBinContent(iv) + gVec.generatedAntiLambda()[iv]); } } for (auto& gVec : geXiMinus) { - if (int(gVec.generatedXiMinus().size()) != hXiMinus->GetNcells()) + if (static_cast(gVec.generatedXiMinus().size()) != hXiMinus->GetNcells()) LOGF(fatal, "XiMinus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedXiMinus().size(), hXiMinus->GetNcells()); for (int iv = 0; iv < hXiMinus->GetNcells(); iv++) { hXiMinus->SetBinContent(iv, hXiMinus->GetBinContent(iv) + gVec.generatedXiMinus()[iv]); } } for (auto& gVec : geXiPlus) { - if (int(gVec.generatedXiPlus().size()) != hXiPlus->GetNcells()) + if (static_cast(gVec.generatedXiPlus().size()) != hXiPlus->GetNcells()) LOGF(fatal, "XiPlus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedXiPlus().size(), hXiPlus->GetNcells()); for (int iv = 0; iv < hXiPlus->GetNcells(); iv++) { hXiPlus->SetBinContent(iv, hXiPlus->GetBinContent(iv) + gVec.generatedXiPlus()[iv]); } } for (auto& gVec : geOmegaMinus) { - if (int(gVec.generatedOmegaMinus().size()) != hOmegaMinus->GetNcells()) + if (static_cast(gVec.generatedOmegaMinus().size()) != hOmegaMinus->GetNcells()) LOGF(fatal, "OmegaMinus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedOmegaMinus().size(), hOmegaMinus->GetNcells()); for (int iv = 0; iv < hOmegaMinus->GetNcells(); iv++) { hOmegaMinus->SetBinContent(iv, hOmegaMinus->GetBinContent(iv) + gVec.generatedOmegaMinus()[iv]); } } for (auto& gVec : geOmegaPlus) { - if (int(gVec.generatedOmegaPlus().size()) != hOmegaPlus->GetNcells()) + if (static_cast(gVec.generatedOmegaPlus().size()) != hOmegaPlus->GetNcells()) LOGF(fatal, "OmegaPlus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedOmegaPlus().size(), hOmegaPlus->GetNcells()); for (int iv = 0; iv < hOmegaPlus->GetNcells(); iv++) { hOmegaPlus->SetBinContent(iv, hOmegaPlus->GetBinContent(iv) + gVec.generatedOmegaPlus()[iv]); diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index 32d7a19d5f0..fca804b8a13 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -707,6 +707,11 @@ struct correlateStrangeness { } // Some QA plots + histos.add("hGeneratedQAPtTrigger", "hGeneratedQAPtTrigger", kTH2F, {axisPtQA, {5, -0.5f, 4.5f}}); + histos.add("hGeneratedQAPtAssociatedK0", "hGeneratedQAPtAssociatedK0", kTH2F, {axisPtQA, {5, -0.5f, 4.5f}}); + histos.add("hClosureQAPtTrigger", "hClosureQAPtTrigger", kTH2F, {axisPtQA, {5, -0.5f, 4.5f}}); + histos.add("hClosureQAPtAssociatedK0", "hClosureQAPtAssociatedK0", kTH2F, {axisPtQA, {5, -0.5f, 4.5f}}); + histos.add("hTrackEtaVsPtVsPhi", "hTrackEtaVsPtVsPhi", kTH3F, {axisPtQA, axisEta, axisPhi}); histos.add("hK0ShortEtaVsPtVsPhi", "hK0ShortEtaVsPtVsPhi", kTH3F, {axisPtQA, axisEta, axisPhi}); histos.add("hK0ShortEtaVsPtVsPhiBg", "hK0ShortEtaVsPtVsPhiBg", kTH3F, {axisPtQA, axisEta, axisPhi}); @@ -726,6 +731,8 @@ struct correlateStrangeness { histos.add("hTriggerPrimaryEtaVsPt", "hTriggerPrimaryEtaVsPt", kTH3F, {axisPtQA, axisEta, axisMult}); histos.add("hTriggerAllSelectedEtaVsPt", "hTriggerAllSelectedEtaVsPt", kTH3F, {axisPtQA, axisEta, axisMult}); + histos.add("hClosureTestEventCounter", "hClosureTestEventCounter", kTH1F, {{10, 0, 10}}); + histos.add("hNumberOfRejectedPairsV0", "hNumberOfRejectedPairsV0", kTH1F, {{1, 0, 1}}); histos.add("hNumberOfRejectedPairsCascades", "hNumberOfRejectedPairsCascades", kTH1F, {{1, 0, 1}}); histos.add("hNumberOfRejectedPairsPions", "hNumberOfRejectedPairsPions", kTH1F, {{1, 0, 1}}); @@ -1168,8 +1175,28 @@ struct correlateStrangeness { } } - void processMCGenerated(aod::McCollision const&, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) + void processMCGenerated(aod::McCollision const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) { + histos.fill(HIST("hClosureTestEventCounter"), 2.5f); + + for (auto const& mcParticle : mcParticles) { + Double_t geta = mcParticle.eta(); + if (std::abs(geta) > 0.8f) { + continue; + } + Double_t gpt = mcParticle.pt(); + if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) { + if (!doTriggPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("hGeneratedQAPtTrigger"), gpt, 0.0f); // step 1: before all selections + } + } + + if (!doAssocPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + if (abs(mcParticle.pdgCode()) == 310 && doCorrelationK0Short) { + histos.fill(HIST("hGeneratedQAPtAssociatedK0"), gpt, 0.0f); // step 1: before all selections + } + } + } for (auto const& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary()) @@ -1245,6 +1272,27 @@ struct correlateStrangeness { if (!bestCollisionINELgtZERO) return; + histos.fill(HIST("hClosureTestEventCounter"), 3.5f); + + for (auto const& mcParticle : mcParticles) { + Double_t geta = mcParticle.eta(); + if (std::abs(geta) > 0.8f) { + continue; + } + Double_t gpt = mcParticle.pt(); + if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) { + if (!doTriggPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("hGeneratedQAPtTrigger"), gpt, 1.0f); // step 2: after event selection + } + } + + if (!doAssocPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + if (abs(mcParticle.pdgCode()) == 310 && doCorrelationK0Short) { + histos.fill(HIST("hGeneratedQAPtAssociatedK0"), gpt, 1.0f); // step 2: before all selections + } + } + } + for (auto const& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary()) { continue; @@ -1290,7 +1338,7 @@ struct correlateStrangeness { } } } - void processClosureTest(aod::McCollision const& collision, soa::SmallGroups> const& recCollisions, aod::McParticles const& mcParticles) + void processClosureTest(aod::McCollision const& mcCollision, soa::SmallGroups> const& recCollisions, aod::McParticles const& mcParticles) { std::vector triggerIndices; @@ -1304,6 +1352,27 @@ struct correlateStrangeness { std::vector omegaMinusIndices; std::vector omegaPlusIndices; + for (auto const& mcParticle : mcParticles) { + Double_t geta = mcParticle.eta(); + if (std::abs(geta) > 0.8f) { + continue; + } + Double_t gpt = mcParticle.pt(); + if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) { + if (!doTriggPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("hClosureQAPtTrigger"), gpt, 0.0f); // step 1: no event selection whatsoever + } + } + + if (!doAssocPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + if (abs(mcParticle.pdgCode()) == 310 && doCorrelationK0Short) { + histos.fill(HIST("hClosureQAPtAssociatedK0"), gpt, 0.0f); // step 1: no event selection whatsoever + } + } + } + + histos.fill(HIST("hClosureTestEventCounter"), 0.5f); + int bestCollisionFT0Mpercentile = -1; float bestCollisionVtxZ = 0.0f; bool bestCollisionSel8 = false; @@ -1330,13 +1399,34 @@ struct correlateStrangeness { } } + histos.fill(HIST("hClosureTestEventCounter"), 1.5f); + + for (auto const& mcParticle : mcParticles) { + Double_t geta = mcParticle.eta(); + if (std::abs(geta) > 0.8f) { + continue; + } + Double_t gpt = mcParticle.pt(); + if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) { + if (!doTriggPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("hClosureQAPtTrigger"), gpt, 1.0f); // step 2: after event selection + } + } + + if (!doAssocPhysicalPrimary || mcParticle.isPhysicalPrimary()) { + if (abs(mcParticle.pdgCode()) == 310 && doCorrelationK0Short) { + histos.fill(HIST("hClosureQAPtAssociatedK0"), gpt, 1.0f); // step 2: after event selection + } + } + } + int iteratorNum = -1; for (auto const& mcParticle : mcParticles) { iteratorNum = iteratorNum + 1; Double_t geta = mcParticle.eta(); Double_t gpt = mcParticle.pt(); Double_t gphi = mcParticle.phi(); - if (abs(geta) > 0.8) { + if (std::abs(geta) > 0.8f) { continue; } if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) { @@ -1416,7 +1506,7 @@ struct correlateStrangeness { continue; if (ptassoc < axisRanges[2][0] || ptassoc > axisRanges[2][1]) continue; - histos.fill(HIST("ClosureTest/sameEvent/") + HIST(particlenames[index]), ComputeDeltaPhi(gphitrigger, gphiassoc), getatrigger - getaassoc, ptassoc, pttrigger, collision.posZ(), bestCollisionFT0Mpercentile); + histos.fill(HIST("ClosureTest/sameEvent/") + HIST(particlenames[index]), ComputeDeltaPhi(gphitrigger, gphiassoc), getatrigger - getaassoc, ptassoc, pttrigger, bestCollisionVtxZ, bestCollisionFT0Mpercentile); } } }); diff --git a/PWGLF/Tasks/Strangeness/v0topologicalcuts.cxx b/PWGLF/Tasks/Strangeness/v0topologicalcuts.cxx index 4a2c8b18d91..246df190f57 100644 --- a/PWGLF/Tasks/Strangeness/v0topologicalcuts.cxx +++ b/PWGLF/Tasks/Strangeness/v0topologicalcuts.cxx @@ -107,22 +107,22 @@ struct v0topologicalcuts { Configurable kzeroshsetting_cospacuts_string{"kzerosetting_cospacuts", {"0_98,0_981,0_982,0_983,0_984,0_985,0_986,0_987,0_988,0_989,0_99,0_991,0_992,0_993,0_994,0_995,0_996,0_997,0_998,0_999"}, "Kzero cosPA Cut Values"}; Configurable kzeroshsetting_dcacuts_string{"kzerosetting_dcacuts", {"0_3,0_285,0_27,0_255,0_24,0_225,0_21,0_195,0_18,0_165,0_15,0_135,0_12,0_105,0_09,0_075,0_06,0_045,0_03,0_015"}, "Kzero DCA Cut Values"}; Configurable kzeroshsetting_v0radius_string{"kzerosetting_v0radiuscuts", {"0_5,0_51,0_52,0_53,0_54,0_55,0_56,0_57,0_58,0_59,0_6,0_61,0_62,0_63,0_64,0_65,0_66,0_67,0_68,0_69"}, "Kzero V0Radius Cut Values"}; - Configurable kzeroshsetting_dcapostopv_string{"kzerosetting_dcapostopvcuts", {"0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Kzero DCA Pos to PV Cut Values"}; - Configurable kzeroshsetting_dcanegtopv_string{"kzerosetting_dcanegtopvcuts", {"0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "KzeroDCA Neg to PV Cut Values"}; + Configurable kzeroshsetting_dcapostopv_string{"kzerosetting_dcapostopvcuts", {"0_0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Kzero DCA Pos to PV Cut Values"}; + Configurable kzeroshsetting_dcanegtopv_string{"kzerosetting_dcanegtopvcuts", {"0_0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "KzeroDCA Neg to PV Cut Values"}; // Configurable strings for Lambdacuts Configurable lambdasetting_cospacuts_string{"lambdasetting_cospacuts", {"0_98,0_981,0_982,0_983,0_984,0_985,0_986,0_987,0_988,0_989,0_99,0_991,0_992,0_993,0_994,0_995,0_996,0_997,0_998,0_999"}, "Lambda cosPA Cut Values"}; Configurable lambdasetting_dcacuts_string{"lambdasetting_dcacuts", {"0_3,0_285,0_27,0_255,0_24,0_225,0_21,0_195,0_18,0_165,0_15,0_135,0_12,0_105,0_09,0_075,0_06,0_045,0_03,0_015"}, "Lambda DCA Cut Values"}; Configurable lambdasetting_v0radius_string{"lambdasetting_v0radiuscuts", {"0_5,0_51,0_52,0_53,0_54,0_55,0_56,0_57,0_58,0_59,0_6,0_61,0_62,0_63,0_64,0_65,0_66,0_67,0_68,0_69"}, "Lambda V0Radius Cut Values"}; - Configurable lambdasetting_dcapostopv_string{"lambdasetting_dcapostopvcuts", {"0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Lambda DCA Pos to PV Cut Values"}; - Configurable lambdasetting_dcanegtopv_string{"lambdasetting_dcanegtopvcuts", {"0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Lambda DCA Neg to PV Cut Values"}; + Configurable lambdasetting_dcapostopv_string{"lambdasetting_dcapostopvcuts", {"0_0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Lambda DCA Pos to PV Cut Values"}; + Configurable lambdasetting_dcanegtopv_string{"lambdasetting_dcanegtopvcuts", {"0_0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Lambda DCA Neg to PV Cut Values"}; // Configurable strings for AntiLambdacuts Configurable antilambdasetting_cospacuts_string{"antilambdasetting_cospacuts", {"0_98,0_981,0_982,0_983,0_984,0_985,0_986,0_987,0_988,0_989,0_99,0_991,0_992,0_993,0_994,0_995,0_996,0_997,0_998,0_999"}, "Antilambda cosPA Cut Values"}; Configurable antilambdasetting_dcacuts_string{"antilambdasetting_dcacuts", {"0_3,0_285,0_27,0_255,0_24,0_225,0_21,0_195,0_18,0_165,0_15,0_135,0_12,0_105,0_09,0_075,0_06,0_045,0_03,0_015"}, "Antilambda DCA Cut Values"}; Configurable antilambdasetting_v0radius_string{"antilambdasetting_v0radiuscuts", {"0_5,0_51,0_52,0_53,0_54,0_55,0_56,0_57,0_58,0_59,0_6,0_61,0_62,0_63,0_64,0_65,0_66,0_67,0_68,0_69"}, "Antilambda V0Radius Cut Values"}; - Configurable antilambdasetting_dcapostopv_string{"antilambdasetting_dcapostopvcuts", {"0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Antilambda DCA Pos to PV Cut Values"}; - Configurable antilambdasetting_dcanegtopv_string{"antilambdasetting_dcanegtopvcuts", {"0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Antilambda DCA Neg to PV Cut Values"}; + Configurable antilambdasetting_dcapostopv_string{"antilambdasetting_dcapostopvcuts", {"0_0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Antilambda DCA Pos to PV Cut Values"}; + Configurable antilambdasetting_dcanegtopv_string{"antilambdasetting_dcanegtopvcuts", {"0_0,0_01,0_02,0_03,0_04,0_05,0_06,0_07,0_08,0_09,0_1,0_11,0_12,0_13,0_14,0_15,0_16,0_17,0_18,0_19"}, "Antilambda DCA Neg to PV Cut Values"}; void init(InitContext const&) { @@ -245,15 +245,15 @@ struct v0topologicalcuts { } // Axes for the three invariant mass plots - AxisSpec K0ShortMassAxis = {nBins, 0.45f, 0.55f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; - AxisSpec LambdaMassAxis = {nBins, 1.085f, 1.145f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; - AxisSpec AntiLambdaMassAxis = {nBins, 1.085f, 1.145f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec K0ShortMassAxis = {nBins, 0.45f, 0.55f, "#it{M} #pi^{+}#pi^{-} [GeV/#it{c}^{2}]"}; + AxisSpec LambdaMassAxis = {nBins, 1.085f, 1.145f, "#it{M} p^{+}#pi^{-} [GeV/#it{c}^{2}]"}; + AxisSpec AntiLambdaMassAxis = {nBins, 1.085f, 1.145f, "#it{M} p^{-}#pi^{+} [GeV/#it{c}^{2}]"}; // adding the invariant mass histograms to their Registries using the namespace for kzeros, lambdas and antilambdas for (int i = 0; i < 20; i++) { cuthistoskzerosh::cospaCut[i] = rKzeroShort_cospaCut.add(fmt::format("hKzerocospaCut_{}", cuthistoskzerosh::cospacuts[i]).data(), fmt::format("hKzerocospaCut_{}", cuthistoskzerosh::cospacuts[i]).data(), {HistType::kTH1D, {{K0ShortMassAxis}}}); cuthistoskzerosh::dcaCut[i] = rKzeroShort_dcaCut.add(fmt::format("hKzerodcaCut_{}", cuthistoskzerosh::dcacuts[i]).data(), fmt::format("hKzerodcaCut_{}", cuthistoskzerosh::dcacuts[i]).data(), {HistType::kTH1D, {{K0ShortMassAxis}}}); - cuthistoskzerosh::v0radiusCut[i] = rKzeroShort_v0radiusCut.add(fmt::format("hKzerov0radiusCut_{}", cuthistoskzerosh::v0radiuscuts[i]).data(), fmt::format("hKzerov0radiusCuts_{}", cuthistoskzerosh::v0radiuscuts[i]).data(), {HistType::kTH1D, {{K0ShortMassAxis}}}); + cuthistoskzerosh::v0radiusCut[i] = rKzeroShort_v0radiusCut.add(fmt::format("hKzerov0radiusCut_{}", cuthistoskzerosh::v0radiuscuts[i]).data(), fmt::format("hKzerov0radiusCut_{}", cuthistoskzerosh::v0radiuscuts[i]).data(), {HistType::kTH1D, {{K0ShortMassAxis}}}); cuthistoskzerosh::dcapostopCut[i] = rKzeroShort_dcapostopCut.add(fmt::format("hKzerodcapostopCut_{}", cuthistoskzerosh::dcapostopvcuts[i]).data(), fmt::format("hKzerodcapostopCut_{}", cuthistoskzerosh::dcapostopvcuts[i]).data(), {HistType::kTH1D, {{K0ShortMassAxis}}}); cuthistoskzerosh::dcanegtopCut[i] = rKzeroShort_dcanegtopCut.add(fmt::format("hKzerodcanegtopCut_{}", cuthistoskzerosh::dcanegtopvcuts[i]).data(), fmt::format("hKzerodcanegtopCut_{}", cuthistoskzerosh::dcanegtopvcuts[i]).data(), {HistType::kTH1D, {{K0ShortMassAxis}}}); } @@ -261,7 +261,7 @@ struct v0topologicalcuts { for (int i = 0; i < 20; i++) { cuthistoslambda::cospaCut[i] = rLambda_cospaCut.add(fmt::format("hLambdacospaCut_{}", cuthistoslambda::cospacuts[i]).data(), fmt::format("hLambdacospaCut_{}", cuthistoslambda::cospacuts[i]).data(), {HistType::kTH1D, {{LambdaMassAxis}}}); cuthistoslambda::dcaCut[i] = rLambda_dcaCut.add(fmt::format("hLambdadcaCut_{}", cuthistoslambda::dcacuts[i]).data(), fmt::format("hLambdadcaCut_{}", cuthistoslambda::dcacuts[i]).data(), {HistType::kTH1D, {{LambdaMassAxis}}}); - cuthistoslambda::v0radiusCut[i] = rLambda_v0radiusCut.add(fmt::format("hLambdav0radiusCut_{}", cuthistoslambda::v0radiuscuts[i]).data(), fmt::format("hLambdav0radiusCuts_{}", cuthistoslambda::v0radiuscuts[i]).data(), {HistType::kTH1D, {{LambdaMassAxis}}}); + cuthistoslambda::v0radiusCut[i] = rLambda_v0radiusCut.add(fmt::format("hLambdav0radiusCut_{}", cuthistoslambda::v0radiuscuts[i]).data(), fmt::format("hLambdav0radiusCut_{}", cuthistoslambda::v0radiuscuts[i]).data(), {HistType::kTH1D, {{LambdaMassAxis}}}); cuthistoslambda::dcapostopCut[i] = rLambda_dcapostopCut.add(fmt::format("hLambdadcapostopCut_{}", cuthistoslambda::dcapostopvcuts[i]).data(), fmt::format("hLambdadcapostopCut_{}", cuthistoslambda::dcapostopvcuts[i]).data(), {HistType::kTH1D, {{LambdaMassAxis}}}); cuthistoslambda::dcanegtopCut[i] = rLambda_dcanegtopCut.add(fmt::format("hLambdadcanegtopCut_{}", cuthistoslambda::dcanegtopvcuts[i]).data(), fmt::format("hLambdadcanegtopCut_{}", cuthistoslambda::dcanegtopvcuts[i]).data(), {HistType::kTH1D, {{LambdaMassAxis}}}); } @@ -269,12 +269,12 @@ struct v0topologicalcuts { for (int i = 0; i < 20; i++) { cuthistosantilambda::cospaCut[i] = rAntiLambda_cospaCut.add(fmt::format("hAntiLambdacospaCut_{}", cuthistosantilambda::cospacuts[i]).data(), fmt::format("hAntiLambdacospaCut_{}", cuthistosantilambda::cospacuts[i]).data(), {HistType::kTH1D, {{AntiLambdaMassAxis}}}); cuthistosantilambda::dcaCut[i] = rAntiLambda_dcaCut.add(fmt::format("hAntiLambdadcaCut_{}", cuthistosantilambda::dcacuts[i]).data(), fmt::format("hAntiLambdadcaCut_{}", cuthistosantilambda::dcacuts[i]).data(), {HistType::kTH1D, {{AntiLambdaMassAxis}}}); - cuthistosantilambda::v0radiusCut[i] = rAntiLambda_v0radiusCut.add(fmt::format("hAntiLambdav0radiusCut_{}", cuthistosantilambda::v0radiuscuts[i]).data(), fmt::format("hAntiLambdav0radiusCuts_{}", cuthistosantilambda::v0radiuscuts[i]).data(), {HistType::kTH1D, {{AntiLambdaMassAxis}}}); + cuthistosantilambda::v0radiusCut[i] = rAntiLambda_v0radiusCut.add(fmt::format("hAntiLambdav0radiusCut_{}", cuthistosantilambda::v0radiuscuts[i]).data(), fmt::format("hAntiLambdav0radiusCut_{}", cuthistosantilambda::v0radiuscuts[i]).data(), {HistType::kTH1D, {{AntiLambdaMassAxis}}}); cuthistosantilambda::dcapostopCut[i] = rAntiLambda_dcapostopCut.add(fmt::format("hAntiLambdadcapostopCut_{}", cuthistosantilambda::dcapostopvcuts[i]).data(), fmt::format("hAntiLambdadcapostopCut_{}", cuthistosantilambda::dcapostopvcuts[i]).data(), {HistType::kTH1D, {{AntiLambdaMassAxis}}}); cuthistosantilambda::dcanegtopCut[i] = rAntiLambda_dcanegtopCut.add(fmt::format("hAntiLambdadcanegtopCut_{}", cuthistosantilambda::dcanegtopvcuts[i]).data(), fmt::format("hAntiLambdadcanegtopCut_{}", cuthistosantilambda::dcanegtopvcuts[i]).data(), {HistType::kTH1D, {{AntiLambdaMassAxis}}}); } - // K0s topological/PID cut histograms added and MC-matched + // K0s topological cut histograms added and MC-matched rV0Parameters_MC_V0match.add("hDCAV0Daughters_V0_Match", "hDCAV0Daughters_No_Match", {HistType::kTH1F, {{nBins, 0.0f, 1.2f}}}); rV0Parameters_MC_V0match.add("hV0CosPA_V0_Match", "hV0CosPA_No_Match", {HistType::kTH1F, {{nBins, 0.95f, 1.f}}}); rV0Parameters_MC_V0match.add("hV0Radius_V0_Match", "hV0Radius_No_Match", {HistType::kTH1F, {{nBins, 0.0f, 5.0f}}}); @@ -300,13 +300,14 @@ struct v0topologicalcuts { rV0Parameters_MC_AntiLambdamatch.add("hDCAV0Daughters_AntiLambdaMC_Match", "hDCAV0Daughters_AntiLambdaMC_Match", {HistType::kTH1F, {{nBins, 0.0f, 1.2f}}}); rV0Parameters_MC_AntiLambdamatch.add("hV0CosPA_AntiLambdaMC_Match", "hV0CosPA_AntiLambdaMC_Match", {HistType::kTH1F, {{nBins, 0.95f, 1.f}}}); rV0Parameters_MC_AntiLambdamatch.add("hV0Radius_AntiLambdaMC_Match", "hV0Radius_AntiLambdaMC_Match", {HistType::kTH1F, {{nBins, 0.2f, 5.0f}}}); - rV0Parameters_MC_AntiLambdamatch.add("hDCAPostoPV_AntiLambdaMC_Match", "hDCANegtoPV_AntiLambdaMC_Match", {HistType::kTH1F, {{nBins, 0.0f, 5.0f}}}); + rV0Parameters_MC_AntiLambdamatch.add("hDCAPostoPV_AntiLambdaMC_Match", "hDCAPostoPV_AntiLambdaMC_Match", {HistType::kTH1F, {{nBins, 0.0f, 5.0f}}}); rV0Parameters_MC_AntiLambdamatch.add("hDCANegtoPV_AntiLambdaMC_Match", "hDCANegtoPV_AntiLambdaMC_Match", {HistType::kTH1F, {{nBins, 0.0f, 5.0f}}}); // V0s Data rV0Parameters_Data.add("hDCAV0Daughters_V0_Data", "hDCAV0Daughters_V0_Data", {HistType::kTH1F, {{nBins, 0.0f, 1.2f}}}); rV0Parameters_Data.add("hV0CosPA_V0_Data", "hV0CosPA_V0_Data", {HistType::kTH1F, {{nBins, 0.95f, 1.f}}}); rV0Parameters_Data.add("hV0Radius_V0_Data", "hV0Radius_V0_Data", {HistType::kTH1F, {{nBins, 0.2f, 5.0f}}}); + rV0Parameters_Data.add("hV0Radius_Full_V0_Data", "hV0Radius_Full_V0_Data", {HistType::kTH1F, {{nBins, 0.2f, 5.0f}}}); rV0Parameters_Data.add("hDCAPostoPV_V0_Data", "hDCAPostoPV_V0_Data", {HistType::kTH1F, {{nBins, 0.0f, 5.0f}}}); rV0Parameters_Data.add("hDCANegtoPV_V0_Data", "hDCANegtoPV_V0_Data", {HistType::kTH1F, {{nBins, 0.0f, 5.0f}}}); rV0Parameters_Data.add("hMassK0ShortNoCuts_V0_Data", "hMassK0ShortNoCuts_V0_Data", {HistType::kTH1F, {{K0ShortMassAxis}}}); @@ -319,7 +320,7 @@ struct v0topologicalcuts { Filter eventFilter = (o2::aod::evsel::sel8 == true); // Defining the type of the daughter tracks - using DaughterTracks = soa::Join; + using DaughterTracks = soa::Join; // This is the Process for the MC reconstructed Data void RecMCprocess(soa::Filtered>::iterator const&, @@ -345,8 +346,8 @@ struct v0topologicalcuts { rV0Parameters_MC_K0Smatch.fill(HIST("hDCAV0Daughters_KzeroMC_Match"), v0.dcaV0daughters()); rV0Parameters_MC_K0Smatch.fill(HIST("hV0CosPA_KzeroMC_Match"), v0.v0cosPA()); rV0Parameters_MC_K0Smatch.fill(HIST("hV0Radius_KzeroMC_Match"), v0.v0radius()); - rV0Parameters_MC_K0Smatch.fill(HIST("hDCAPostoPV_KzeroMC_Match"), v0.dcapostopv()); - rV0Parameters_MC_K0Smatch.fill(HIST("hDCANegtoPV_KzeroMC_Match"), v0.dcanegtopv()); + rV0Parameters_MC_K0Smatch.fill(HIST("hDCAPostoPV_KzeroMC_Match"), TMath::Abs(v0.dcapostopv())); + rV0Parameters_MC_K0Smatch.fill(HIST("hDCANegtoPV_KzeroMC_Match"), TMath::Abs(v0.dcanegtopv())); for (int j = 0; j < 20; j++) { std::string cospacut = cuthistoskzerosh::cospacuts[j]; // Get the current cut value from the namespace @@ -380,7 +381,7 @@ struct v0topologicalcuts { size_t pos = dcapostopcut.find("_"); dcapostopcut[pos] = '.'; const float dcapostopcutvalue = std::stod(dcapostopcut); - if (v0.dcapostopv() > dcapostopcutvalue) { + if (TMath::Abs(v0.dcapostopv()) > dcapostopcutvalue) { cuthistoskzerosh::dcapostopCut[j]->Fill(v0.mK0Short()); } } @@ -389,7 +390,7 @@ struct v0topologicalcuts { size_t pos = dcanegtopcut.find("_"); dcanegtopcut[pos] = '.'; const float dcanegtopcutvalue = std::stod(dcanegtopcut); - if (v0.dcanegtopv() > dcanegtopcutvalue) { + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopcutvalue) { cuthistoskzerosh::dcanegtopCut[j]->Fill(v0.mK0Short()); } } @@ -398,8 +399,8 @@ struct v0topologicalcuts { rV0Parameters_MC_Lambdamatch.fill(HIST("hDCAV0Daughters_LambdaMC_Match"), v0.dcaV0daughters()); rV0Parameters_MC_Lambdamatch.fill(HIST("hV0CosPA_LambdaMC_Match"), v0.v0cosPA()); rV0Parameters_MC_Lambdamatch.fill(HIST("hV0Radius_LambdaMC_Match"), v0.v0radius()); - rV0Parameters_MC_Lambdamatch.fill(HIST("hDCAPostoPV_LambdaMC_Match"), v0.dcapostopv()); - rV0Parameters_MC_Lambdamatch.fill(HIST("hDCANegtoPV_LambdaMC_Match"), v0.dcanegtopv()); + rV0Parameters_MC_Lambdamatch.fill(HIST("hDCAPostoPV_LambdaMC_Match"), TMath::Abs(v0.dcapostopv())); + rV0Parameters_MC_Lambdamatch.fill(HIST("hDCANegtoPV_LambdaMC_Match"), TMath::Abs(v0.dcanegtopv())); // for explanation look at the first Kzero plot above for (int j = 0; j < 20; j++) { @@ -434,7 +435,7 @@ struct v0topologicalcuts { size_t pos = dcapostopcutlambda.find("_"); dcapostopcutlambda[pos] = '.'; const float dcapostopcutlambdavalue = std::stod(dcapostopcutlambda); - if (v0.dcapostopv() > dcapostopcutlambdavalue) { + if (TMath::Abs(v0.dcapostopv()) > dcapostopcutlambdavalue) { cuthistoslambda::dcapostopCut[j]->Fill(v0.mLambda()); } } @@ -443,7 +444,7 @@ struct v0topologicalcuts { size_t pos = dcanegtopcutlambda.find("_"); dcanegtopcutlambda[pos] = '.'; const float dcanegtopcutlambdavalue = std::stod(dcanegtopcutlambda); - if (v0.dcanegtopv() > dcanegtopcutlambdavalue) { + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopcutlambdavalue) { cuthistoslambda::dcanegtopCut[j]->Fill(v0.mLambda()); } } @@ -452,8 +453,8 @@ struct v0topologicalcuts { rV0Parameters_MC_AntiLambdamatch.fill(HIST("hDCAV0Daughters_AntiLambdaMC_Match"), v0.dcaV0daughters()); rV0Parameters_MC_AntiLambdamatch.fill(HIST("hV0CosPA_AntiLambdaMC_Match"), v0.v0cosPA()); rV0Parameters_MC_AntiLambdamatch.fill(HIST("hV0Radius_AntiLambdaMC_Match"), v0.v0radius()); - rV0Parameters_MC_AntiLambdamatch.fill(HIST("hDCAPostoPV_AntiLambdaMC_Match"), v0.dcapostopv()); - rV0Parameters_MC_AntiLambdamatch.fill(HIST("hDCANegtoPV_AntiLambdaMC_Match"), v0.dcanegtopv()); + rV0Parameters_MC_AntiLambdamatch.fill(HIST("hDCAPostoPV_AntiLambdaMC_Match"), TMath::Abs(v0.dcapostopv())); + rV0Parameters_MC_AntiLambdamatch.fill(HIST("hDCANegtoPV_AntiLambdaMC_Match"), TMath::Abs(v0.dcanegtopv())); // for explanation look at the first Kzero plot above for (int j = 0; j < 20; j++) { std::string cospacutantilambda = cuthistosantilambda::cospacuts[j]; @@ -487,7 +488,7 @@ struct v0topologicalcuts { size_t pos = dcapostopantilambda.find("_"); dcapostopantilambda[pos] = '.'; const float dcapostopcutantilambdavalue = std::stod(dcapostopantilambda); - if (v0.dcapostopv() > dcapostopcutantilambdavalue) { + if (TMath::Abs(v0.dcapostopv()) > dcapostopcutantilambdavalue) { cuthistosantilambda::dcapostopCut[j]->Fill(v0.mAntiLambda()); } } @@ -496,7 +497,7 @@ struct v0topologicalcuts { size_t pos = dcanegtopantilambda.find("_"); dcanegtopantilambda[pos] = '.'; const float dcanegtopcutantilambdavalue = std::stod(dcanegtopantilambda); - if (v0.dcanegtopv() > dcanegtopcutantilambdavalue) { + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopcutantilambdavalue) { cuthistosantilambda::dcanegtopCut[j]->Fill(v0.mAntiLambda()); } } @@ -512,13 +513,13 @@ struct v0topologicalcuts { for (const auto& v0 : V0s) { rV0Parameters_Data.fill(HIST("hMassK0ShortNoCuts_V0_Data"), v0.mK0Short()); rV0Parameters_Data.fill(HIST("hMassLambdaNoCuts_V0_Data"), v0.mLambda()); - rV0Parameters_Data.fill(HIST("hMassAntiLambdaNoCuts_V0_Data"), v0.mAntiLambda()); + rV0Parameters_Data.fill(HIST("hMassAntilambdaNoCuts_V0_Data"), v0.mAntiLambda()); rV0Parameters_Data.fill(HIST("hDCAV0Daughters_V0_Data"), v0.dcaV0daughters()); rV0Parameters_Data.fill(HIST("hV0CosPA_V0_Data"), v0.v0cosPA()); rV0Parameters_Data.fill(HIST("hV0Radius_V0_Data"), v0.v0radius()); rV0Parameters_Data.fill(HIST("hV0Radius_Full_V0_Data"), v0.v0radius()); - rV0Parameters_Data.fill(HIST("hDCAPostoPV_V0_Data"), v0.dcapostopv()); - rV0Parameters_Data.fill(HIST("hDCANegtoPV_V0_Data"), v0.dcanegtopv()); + rV0Parameters_Data.fill(HIST("hDCAPostoPV_V0_Data"), TMath::Abs(v0.dcapostopv())); + rV0Parameters_Data.fill(HIST("hDCANegtoPV_V0_Data"), TMath::Abs(v0.dcanegtopv())); // Filling the five Kzero invariant mass plots for different cuts (which are taken from namespace), for full explanation see the first kzero cut filling in the MC process for (int j = 0; j < 20; j++) { @@ -553,7 +554,7 @@ struct v0topologicalcuts { size_t pos = dcapostopcut.find("_"); dcapostopcut[pos] = '.'; const float dcapostopcutvalue = std::stod(dcapostopcut); - if (v0.dcapostopv() > dcapostopcutvalue) { + if (TMath::Abs(v0.dcapostopv()) > dcapostopcutvalue) { cuthistoskzerosh::dcapostopCut[j]->Fill(v0.mK0Short()); } } @@ -562,7 +563,7 @@ struct v0topologicalcuts { size_t pos = dcanegtopcut.find("_"); dcanegtopcut[pos] = '.'; const float dcanegtopcutvalue = std::stod(dcanegtopcut); - if (v0.dcanegtopv() > dcanegtopcutvalue) { + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopcutvalue) { cuthistoskzerosh::dcanegtopCut[j]->Fill(v0.mK0Short()); } } @@ -599,7 +600,7 @@ struct v0topologicalcuts { size_t pos = dcapostopcutlambda.find("_"); dcapostopcutlambda[pos] = '.'; const float dcapostopcutlambdavalue = std::stod(dcapostopcutlambda); - if (v0.dcapostopv() > dcapostopcutlambdavalue) { + if (TMath::Abs(v0.dcapostopv()) > dcapostopcutlambdavalue) { cuthistoslambda::dcapostopCut[j]->Fill(v0.mLambda()); } } @@ -608,11 +609,11 @@ struct v0topologicalcuts { size_t pos = dcanegtopcutlambda.find("_"); dcanegtopcutlambda[pos] = '.'; const float dcanegtopcutlambdavalue = std::stod(dcanegtopcutlambda); - if (v0.dcanegtopv() > dcanegtopcutlambdavalue) { + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopcutlambdavalue) { cuthistoslambda::dcanegtopCut[j]->Fill(v0.mLambda()); } } - // Filling the five Lambda invariant mass plots for different cuts (which are taken from namespace), same as with Kzeros and Lambdas above,for full explanation see the first kzero cut filling in the MC process + // Filling the five Anti-Lambda invariant mass plots for different cuts (which are taken from namespace), same as with Kzeros and Lambdas above,for full explanation see the first kzero cut filling in the MC process for (int j = 0; j < 20; j++) { std::string cospacutantilambda = cuthistosantilambda::cospacuts[j]; size_t pos = cospacutantilambda.find("_"); @@ -645,7 +646,7 @@ struct v0topologicalcuts { size_t pos = dcapostopantilambda.find("_"); dcapostopantilambda[pos] = '.'; const float dcapostopcutantilambdavalue = std::stod(dcapostopantilambda); - if (v0.dcapostopv() > dcapostopcutantilambdavalue) { + if (TMath::Abs(v0.dcapostopv()) > dcapostopcutantilambdavalue) { cuthistosantilambda::dcapostopCut[j]->Fill(v0.mAntiLambda()); } } @@ -654,13 +655,12 @@ struct v0topologicalcuts { size_t pos = dcanegtopantilambda.find("_"); dcanegtopantilambda[pos] = '.'; const float dcanegtopcutantilambdavalue = std::stod(dcanegtopantilambda); - if (v0.dcanegtopv() > dcanegtopcutantilambdavalue) { + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopcutantilambdavalue) { cuthistosantilambda::dcanegtopCut[j]->Fill(v0.mAntiLambda()); } } } } - PROCESS_SWITCH(v0topologicalcuts, RecMCprocess, "Process Run 3 MC:Reconstructed", true); PROCESS_SWITCH(v0topologicalcuts, Dataprocess, "Process Run 3 Data,", false); }; diff --git a/PWGUD/Tasks/eventByevent.cxx b/PWGUD/Tasks/eventByevent.cxx index 0ed0037101a..3df594af546 100644 --- a/PWGUD/Tasks/eventByevent.cxx +++ b/PWGUD/Tasks/eventByevent.cxx @@ -36,13 +36,13 @@ namespace o2::aod { namespace tree { -DECLARE_SOA_COLUMN(GAPSIDE, gapside, int); -DECLARE_SOA_COLUMN(FT0AAMP, ft0Aamp, float); // namespace udzdc -DECLARE_SOA_COLUMN(FT0CAMP, ft0Camp, float); -DECLARE_SOA_COLUMN(FDDAAMP, fddAamp, float); -DECLARE_SOA_COLUMN(FDDCAMP, fddCamp, float); -DECLARE_SOA_COLUMN(FV0AAMP, fv0Aamp, float); -// ZDC tables +// DECLARE_SOA_COLUMN(GAPSIDE, gapside, int); +// DECLARE_SOA_COLUMN(FT0AAMP, ft0Aamp, float); // namespace udzdc +// DECLARE_SOA_COLUMN(FT0CAMP, ft0Camp, float); +// DECLARE_SOA_COLUMN(FDDAAMP, fddAamp, float); +// DECLARE_SOA_COLUMN(FDDCAMP, fddCamp, float); +// DECLARE_SOA_COLUMN(FV0AAMP, fv0Aamp, float); +// ZDC tables DECLARE_SOA_COLUMN(ZAENERGY, zaenergy, float); // namespace udzdc DECLARE_SOA_COLUMN(ZCENERGY, zcenergy, float); // track tables @@ -70,19 +70,19 @@ DECLARE_SOA_COLUMN(PTS, Pts, std::vector); DECLARE_SOA_COLUMN(ETAS, etas, std::vector); DECLARE_SOA_COLUMN(PHIS, Phis, std::vector); DECLARE_SOA_COLUMN(SIGNS, Signs, std::vector); -DECLARE_SOA_COLUMN(RAWTRACKS, rawtracks, int); -DECLARE_SOA_COLUMN(PTRACKS, ptracks, int); +// DECLARE_SOA_COLUMN(RAWTRACKS, rawtracks, int); +// DECLARE_SOA_COLUMN(PTRACKS, ptracks, int); // DECLARE_SOA_COLUMN(NTPCCLS, ntpccls,int); } // namespace tree DECLARE_SOA_TABLE(TREE, "AOD", "Tree", //! ZDC information - tree::GAPSIDE, - tree::FT0AAMP, - tree::FT0CAMP, - tree::FDDAAMP, - tree::FDDCAMP, - tree::FV0AAMP, + // tree::GAPSIDE, + // tree::FT0AAMP, + // tree::FT0CAMP, + // tree::FDDAAMP, + // tree::FDDCAMP, + // tree::FV0AAMP, tree::ZAENERGY, tree::ZCENERGY, tree::PT, @@ -107,9 +107,10 @@ DECLARE_SOA_TABLE(TREE, "AOD", "Tree", //! ZDC information tree::PTS, tree::ETAS, tree::PHIS, - tree::SIGNS, - tree::RAWTRACKS, - tree::PTRACKS); + tree::SIGNS + // tree::RAWTRACKS, + // tree::PTRACKS +); } // namespace o2::aod @@ -177,7 +178,7 @@ struct EventByEvent { } using udtracks = soa::Join; - using udtracksfull = soa::Join; + using udtracksfull = soa::Join; using UDCollisionsFull = soa::Join; //__________________________________________________________________________ // Main process @@ -218,141 +219,77 @@ struct EventByEvent { TLorentzVector p; - /* float pipid1; - float pipid2; - float pipid3; - float pipid4; - float kpid1; - float kpid2; - float kpid3; - float kpid4; - float elpid1; - float elpid2; - float elpid3; - float elpid4;*/ - - // registry.fill(HIST("hTracks"), tracks.size()); - - if (collision.numContrib() > collcontrib_cut) - return; + if (gapSide == gap_Side) { - registry.fill(HIST("hSelectionCounter"), 4); - if ((collision.posZ() < -(Zvtx_cut)) || (collision.posZ() > Zvtx_cut)) - return; - registry.fill(HIST("hSelectionCounter"), 5); + // registry.fill(HIST("hTracks"), tracks.size()); - for (auto t : tracks) { - if (!t.isPVContributor()) { - continue; - } + if (collision.numContrib() > collcontrib_cut) + return; - int NFindable = t.tpcNClsFindable(); - int NMinusFound = t.tpcNClsFindableMinusFound(); - int NCluster = NFindable - NMinusFound; + registry.fill(HIST("hSelectionCounter"), 4); + if ((collision.posZ() < -(Zvtx_cut)) || (collision.posZ() > Zvtx_cut)) + return; + registry.fill(HIST("hSelectionCounter"), 5); - if (NCluster < TPC_cluster) { - continue; - } + for (auto t : tracks) { - double dEdx = t.tpcSignal(); + if (!trackselector(t, parameters)) + continue; - registry.fill(HIST("hdEdx"), t.tpcInnerParam() / t.sign(), dEdx); - TLorentzVector a; - a.SetXYZM(t.px(), t.py(), t.pz(), o2::constants::physics::MassPionCharged); - allTracks.push_back(a); - auto nSigmaPi = t.tpcNSigmaPi(); + double dEdx = t.tpcSignal(); - if (fabs(nSigmaPi) < PID_cut) { - onlyPionTracks.push_back(a); - onlyPionSigma.push_back(nSigmaPi); - rawPionTracks.push_back(t); - registry.fill(HIST("hdEdxPion"), t.tpcInnerParam() / t.sign(), dEdx); + registry.fill(HIST("hdEdx"), t.tpcInnerParam() / t.sign(), dEdx); + TLorentzVector a; + a.SetXYZM(t.px(), t.py(), t.pz(), o2::constants::physics::MassPionCharged); + allTracks.push_back(a); + auto nSigmaPi = t.tpcNSigmaPi(); + + if (fabs(nSigmaPi) < PID_cut) { + onlyPionTracks.push_back(a); + onlyPionSigma.push_back(nSigmaPi); + rawPionTracks.push_back(t); + registry.fill(HIST("hdEdxPion"), t.tpcInnerParam() / t.sign(), dEdx); + } } - } - registry.fill(HIST("hTracksPions"), onlyPionTracks.size()); + registry.fill(HIST("hTracksPions"), onlyPionTracks.size()); - //_____________________________________ - if (collision.numContrib() >= 2) { - // Four pions analysis - registry.fill(HIST("hSelectionCounter"), 6); - if ((rawPionTracks.size() >= 2) && (allTracks.size() >= 2)) { + //_____________________________________ + if (collision.numContrib() >= 2) { + // Four pions analysis + registry.fill(HIST("hSelectionCounter"), 6); + if ((rawPionTracks.size() >= 2) && (allTracks.size() >= 2)) { - for (auto pion : onlyPionTracks) { - p += pion; - } + for (auto pion : onlyPionTracks) { + p += pion; + } - registry.fill(HIST("h4TracksPions"), onlyPionTracks.size()); - registry.fill(HIST("hSelectionCounter"), 7); - - for (auto rtrk : rawPionTracks) { - - TLorentzVector itrk; - itrk.SetXYZM(rtrk.px(), rtrk.py(), rtrk.pz(), o2::constants::physics::MassPionCharged); - trackpt.push_back(itrk.Pt()); - tracketa.push_back(itrk.Eta()); - trackphi.push_back(itrk.Phi()); - tracksign.push_back(rtrk.sign()); - pitpcpid.push_back(rtrk.tpcNSigmaPi()); - ktpcpid.push_back(rtrk.tpcNSigmaKa()); - eltpcpid.push_back(rtrk.tpcNSigmaEl()); - prtpcpid.push_back(rtrk.tpcNSigmaPr()); - } + registry.fill(HIST("h4TracksPions"), onlyPionTracks.size()); + registry.fill(HIST("hSelectionCounter"), 7); + + for (auto rtrk : rawPionTracks) { + + TLorentzVector itrk; + itrk.SetXYZM(rtrk.px(), rtrk.py(), rtrk.pz(), o2::constants::physics::MassPionCharged); + trackpt.push_back(itrk.Pt()); + tracketa.push_back(itrk.Eta()); + trackphi.push_back(itrk.Phi()); + tracksign.push_back(rtrk.sign()); + pitpcpid.push_back(rtrk.tpcNSigmaPi()); + ktpcpid.push_back(rtrk.tpcNSigmaKa()); + eltpcpid.push_back(rtrk.tpcNSigmaEl()); + prtpcpid.push_back(rtrk.tpcNSigmaPr()); + } - /* trackpt.push_back(onlyPionTracks[0].Pt()); - trackpt.push_back(onlyPionTracks[1].Pt()); - trackpt.push_back(onlyPionTracks[2].Pt()); - trackpt.push_back(onlyPionTracks[3].Pt()); - - tracketa.push_back(onlyPionTracks[0].Eta()); - tracketa.push_back(onlyPionTracks[1].Eta()); - tracketa.push_back(onlyPionTracks[2].Eta()); - tracketa.push_back(onlyPionTracks[3].Eta()); - - trackphi.push_back(onlyPionTracks[0].Phi()); - trackphi.push_back(onlyPionTracks[1].Phi()); - trackphi.push_back(onlyPionTracks[2].Phi()); - trackphi.push_back(onlyPionTracks[3].Phi()); - - tracksign.push_back(rawPionTracks[0].sign()); - tracksign.push_back(rawPionTracks[1].sign()); - tracksign.push_back(rawPionTracks[2].sign()); - tracksign.push_back(rawPionTracks[3].sign()); - - pipid1 =rawPionTracks[0].tpcNSigmaPi(); - pipid2 =rawPionTracks[1].tpcNSigmaPi(); - pipid3 =rawPionTracks[2].tpcNSigmaPi(); - pipid4 =rawPionTracks[3].tpcNSigmaPi(); - - kpid1 = rawPionTracks[0].tpcNSigmaKa(); - kpid2 = rawPionTracks[1].tpcNSigmaKa(); - kpid3 = rawPionTracks[2].tpcNSigmaKa(); - kpid4 = rawPionTracks[3].tpcNSigmaKa(); - - elpid1 =rawPionTracks[0].tpcNSigmaEl(); - elpid2 =rawPionTracks[1].tpcNSigmaEl(); - elpid3 =rawPionTracks[2].tpcNSigmaEl(); - elpid4 =rawPionTracks[3].tpcNSigmaEl();*/ - - int sign = 0; - TLorentzVector piplus, piminus; - for (auto rawPion : rawPionTracks) { - sign += rawPion.sign(); - if (rawPion.sign() > 0) { - piplus = onlyPionTracks[0]; - piplus = onlyPionTracks[1]; - piplus = onlyPionTracks[2]; - piplus = onlyPionTracks[3]; - } else if (rawPion.sign() < 0) { - piminus = onlyPionTracks[0]; - piminus = onlyPionTracks[1]; - piminus = onlyPionTracks[2]; - piminus = onlyPionTracks[3]; + int sign = 0; + TLorentzVector piplus, piminus; + for (auto rawPion : rawPionTracks) { + sign += rawPion.sign(); } - } - registry.fill(HIST("hTracks"), collision.numContrib()); - // tree(gapSide,collision.totalFT0AmplitudeA(),collision.totalFT0AmplitudeC(),collision.totalFDDAmplitudeA(),collision.totalFDDAmplitudeC(),collision.totalFV0AmplitudeA(), collision.energyCommonZNA(), collision.energyCommonZNC(), p.Pt(),p.Y(),p.Phi(),p.M(),sign,collision.numContrib(),pipid1,pipid2,pipid3,pipid4,kpid1,kpid2,kpid3,kpid4,elpid1,elpid2,elpid3,elpid4,trackpt,tracketa,trackphi,tracksign); - tree(gapSide, collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), collision.totalFV0AmplitudeA(), collision.energyCommonZNA(), collision.energyCommonZNC(), p.Pt(), p.Y(), p.Phi(), p.M(), sign, collision.numContrib(), pitpcpid, ktpcpid, eltpcpid, prtpcpid, trackpt, tracketa, trackphi, tracksign, allTracks.size(), rawPionTracks.size()); + registry.fill(HIST("hTracks"), collision.numContrib()); + + tree(collision.energyCommonZNA(), collision.energyCommonZNC(), p.Pt(), p.Y(), p.Phi(), p.M(), sign, collision.numContrib(), pitpcpid, ktpcpid, eltpcpid, prtpcpid, trackpt, tracketa, trackphi, tracksign); + } } } } diff --git a/PWGUD/Tasks/upcPionAnalysis.cxx b/PWGUD/Tasks/upcPionAnalysis.cxx index bd7157dc702..8cab0acb000 100644 --- a/PWGUD/Tasks/upcPionAnalysis.cxx +++ b/PWGUD/Tasks/upcPionAnalysis.cxx @@ -67,7 +67,7 @@ struct UPCPionAnalysis { // defining histograms using histogram registry HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - //_____________________________________________________________________________ + //_____________________________________________________________________________________________ Double_t CosThetaHelicityFrame(TLorentzVector pionPositive, TLorentzVector pionNegative, TLorentzVector possibleRhoZero) @@ -405,7 +405,7 @@ struct UPCPionAnalysis { registry.add("hCostheta6Pion", "Costheta;#it{Cos#Theta};", kTH1F, {{300, -1.5, 1.5}}); registry.add("hCostheta8Pion", "Costheta;#it{Cos#Theta};", kTH1F, {{300, -1.5, 1.5}}); - // using Angular Correlation method + // Using Angular Correlation method registry.add("TwoPion/Coherent/AccoplAngle", "AccoplAngle", kTH1F, {{250, -0.2, 0.2}}); registry.add("TwoPion/Coherent/CosTheta", "CosTheta", kTH1F, {{300, -1.5, 1.5}}); @@ -427,7 +427,7 @@ struct UPCPionAnalysis { } using udtracks = soa::Join; - using udtracksfull = soa::Join; + using udtracksfull = soa::Join; using UDCollisionsFull = soa::Join; //__________________________________________________________________________ // Main process @@ -476,17 +476,21 @@ struct UPCPionAnalysis { registry.fill(HIST("hSelectionCounter"), 5); for (auto t : tracks) { - if (!t.isPVContributor()) { + + /*if (!t.isPVContributor()) { + continue; + }*/ + + if (!trackselector(t, parameters)) continue; - } int NFindable = t.tpcNClsFindable(); int NMinusFound = t.tpcNClsFindableMinusFound(); int NCluster = NFindable - NMinusFound; - if (NCluster < TPC_cluster) { - continue; - } + /*if (NCluster < TPC_cluster) { + continue; + }*/ double dEdx = t.tpcSignal(); @@ -586,7 +590,7 @@ struct UPCPionAnalysis { } } } - //_____________________________________ + //_____________________________________________________________________________________________________ // Six pions analysis if (collision.numContrib() == 6) { if ((rawPionTracks.size() == 6) && (onlyPionTracks.size() == 6)) { diff --git a/Tools/PIDML/pidMLProducer.cxx b/Tools/PIDML/pidMLProducer.cxx index 68f85daac98..67cf4308a5e 100644 --- a/Tools/PIDML/pidMLProducer.cxx +++ b/Tools/PIDML/pidMLProducer.cxx @@ -190,11 +190,35 @@ struct PidMlProducer { } } + template + float getTOFSignal(T const& track) + { + return tofMissing(track) ? std::numeric_limits::quiet_NaN() : track.tofSignal(); + } + + template + float getTOFBeta(T const& track) + { + return tofMissing(track) ? std::numeric_limits::quiet_NaN() : track.beta(); + } + + template + float getTRDSignal(T const& track) + { + return trdMissing(track) ? std::numeric_limits::quiet_NaN() : track.trdSignal(); + } + + template + uint8_t getTRDPattern(T const& track) + { + return trdMissing(track) ? static_cast(0U) : track.trdPattern(); + } + void processDataML(MyCollisionML const& /*collision*/, BigTracksDataML const& tracks) { for (const auto& track : tracks) { - pidTracksTableDataML(track.tpcSignal(), track.trdSignal(), track.trdPattern(), - track.tofSignal(), track.beta(), + pidTracksTableDataML(track.tpcSignal(), getTRDSignal(track), getTRDPattern(track), + getTOFSignal(track), getTOFBeta(track), track.p(), track.pt(), track.px(), track.py(), track.pz(), track.sign(), track.x(), track.y(), track.z(), @@ -216,9 +240,9 @@ struct PidMlProducer { collision.multFT0A(), collision.multFT0C(), collision.multFT0M(), collision.multZNA(), collision.multZNC(), collision.multTracklets(), collision.multTPC(), - track.tpcSignal(), track.trdSignal(), track.trdPattern(), + track.tpcSignal(), getTRDSignal(track), getTRDPattern(track), track.trackEtaEmcal(), track.trackPhiEmcal(), - track.tofSignal(), track.beta(), + getTOFSignal(track), getTOFBeta(track), track.p(), track.pt(), track.px(), track.py(), track.pz(), track.sign(), track.x(), track.y(), track.z(), @@ -251,8 +275,8 @@ struct PidMlProducer { const auto mcParticle = track.mcParticle_as(); uint8_t isPrimary = static_cast(mcParticle.isPhysicalPrimary()); uint32_t pdgCode = mcParticle.pdgCode(); - pidTracksTableMCML(track.tpcSignal(), track.trdSignal(), track.trdPattern(), - track.tofSignal(), track.beta(), + pidTracksTableMCML(track.tpcSignal(), getTRDSignal(track), getTRDPattern(track), + getTOFSignal(track), getTOFBeta(track), track.p(), track.pt(), track.px(), track.py(), track.pz(), track.sign(), track.x(), track.y(), track.z(), @@ -282,9 +306,9 @@ struct PidMlProducer { collision.multFT0A(), collision.multFT0C(), collision.multFT0M(), collision.multZNA(), collision.multZNC(), collision.multTracklets(), collision.multTPC(), - track.tpcSignal(), track.trdSignal(), track.trdPattern(), + track.tpcSignal(), getTRDSignal(track), getTRDPattern(track), track.trackEtaEmcal(), track.trackPhiEmcal(), - track.tofSignal(), track.beta(), + getTOFSignal(track), getTOFBeta(track), track.p(), track.pt(), track.px(), track.py(), track.pz(), track.sign(), track.x(), track.y(), track.z(),