diff --git a/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx b/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx index ed1913420d5..5d63cc48434 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx @@ -276,10 +276,10 @@ struct OnTheFlyTOFPID { if (scalarProduct1 > scalarProduct2) { modulus = std::hypot(point1[0] - trcCircle.xC, point1[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[0] - trcCircle.yC); + cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); } else { modulus = std::hypot(point2[0] - trcCircle.xC, point2[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[0] - trcCircle.yC); + cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); } cosAngle /= modulus; length = trcCircle.rC * TMath::ACos(cosAngle); diff --git a/CODEOWNERS b/CODEOWNERS index a1123028fa1..4c222d06b34 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -29,7 +29,7 @@ /PWGDQ @alibuild @iarsene @dsekihat @feisenhu @lucamicheletti93 /PWGEM @alibuild @mikesas @rbailhac @feisenhu /PWGEM/Dilepton @alibuild @mikesas @rbailhac @dsekihat @ivorobye @feisenhu -/PWGEM/PhotonMeson @alibuild @mikesas @rbailhac @m-c-danisch @novitzky @mhemmer-cern +/PWGEM/PhotonMeson @alibuild @mikesas @rbailhac @m-c-danisch @novitzky @mhemmer-cern @dsekihat /PWGHF @alibuild @vkucera @fcolamar @fgrosa @fcatalan92 @mfaggin @mmazzilli @deepathoms @nzardosh @NicoleBastid /PWGLF @alibuild @lramona @alcaliva @lbariogl @chiarapinto @BongHwi @lbarnby @mbombara @iravasen @njacazio @ChiaraDeMartin95 @skundu692 /PWGMM @alibuild @aalkin diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 7dea5b7ddda..d4cd080b9ee 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -288,10 +288,10 @@ struct femtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); @@ -874,15 +874,27 @@ struct femtoUniverseProducerTask { processFullData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s) /// \todo with FilteredFullV0s + o2::aod::V0Datas const& fullV0s) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); // fill the tables fillCollisionsAndTracksAndV0AndPhi(col, tracks, fullV0s); } - PROCESS_SWITCH(femtoUniverseProducerTask, processFullData, - "Provide experimental data", false); + PROCESS_SWITCH(femtoUniverseProducerTask, processFullData, "Provide experimental data", false); + + void + processTrackV0(aod::FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + soa::Filtered const& tracks, + o2::aod::V0Datas const& fullV0s) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + // fill the tables + fillCollisionsAndTracksAndV0AndPhi(col, tracks, fullV0s); + } + PROCESS_SWITCH(femtoUniverseProducerTask, processTrackV0, "Provide experimental data for track v0", true); void processFullMC(aod::FemtoFullCollisionMC const& col, @@ -890,7 +902,7 @@ struct femtoUniverseProducerTask { soa::Join const& tracks, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles, - soa::Join const& fullV0s) /// \todo with FilteredFullV0s + soa::Join const& fullV0s) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); @@ -917,7 +929,7 @@ struct femtoUniverseProducerTask { void processTrackData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks) /// \todo with FilteredFullV0s + aod::FemtoFullTracks const& tracks) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); @@ -926,7 +938,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); } PROCESS_SWITCH(femtoUniverseProducerTask, processTrackData, - "Provide experimental data for track track", true); + "Provide experimental data for track track", false); // using FilteredFemtoFullTracks = soa::Filtered; void processTrackPhiData(aod::FemtoFullCollision const& col, diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx index 7de3a9db2a8..edb0b5abb7c 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx @@ -13,6 +13,7 @@ /// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zuzanna.chochulska.stud@pw.edu.pl +/// \author Shirajum Monira, WUT Warsaw, shirajum.monira.dokt@pw.edu.pl #include #include "Framework/AnalysisTask.h" @@ -21,7 +22,6 @@ #include "Framework/ASoAHelpers.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" - #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" @@ -35,59 +35,46 @@ using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::femtoUniverse; - -namespace -{ -static constexpr int nTrack = 1; -static constexpr int nV0Children = 2; -static constexpr int nCuts = 5; -static const std::vector TrackName{"Track"}; -static const std::vector V0ChildrenName{"PosChild", "NegChild"}; -static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; -static const float cutsTableTrack[nTrack][nCuts]{{4.05f, 0.75f, 3.f, 3.f, 100.f}}; -static const float cutsTableV0Children[nV0Children][nCuts]{ - {90.f, 99.f, 5.f, 5.f, 100.f}, - {90.f, 99.f, 5.f, 5.f, 100.f}}; -} // namespace +using namespace o2::aod::pidutils; struct femtoUniversePairTaskTrackV0 { + SliceCache cache; - Preslice perCol = aod::femtouniverseparticle::fdCollisionId; - - /// Particle 1 (track) - Configurable> ConfTrkCutTable{"ConfTrkCutTable", {cutsTableTrack[0], nTrack, nCuts, TrackName, cutNames}, "Particle selections"}; - Configurable ConfTrkPDGCodePartOne{"ConfTrkPDGCodePartOne", 2212, "Particle 1 (Track) - PDG code"}; - Configurable ConfTrkCutPartOne{"ConfTrkCutPartOne", 5542474, "Particle 1 (Track) - Selection bit from cutCulator"}; - Configurable ConfTrkPIDPartOne{"ConfTrkPIDPartOne", 2, "Particle 1 - Read from cutCulator"}; - Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; - Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; + // using FemtoFullParticles = soa::Join; + using FemtoFullParticles = soa::Join; + Preslice perCol = aod::femtouniverseparticle::fdCollisionId; + + /// Particle 1 (from track) + Configurable ConfTrkPDGCodePartOne{"ConfTrkPDGCodePartOne", 211, "Particle 1 (Track) - PDG code"}; + Configurable ConfTrackChoicePartOne{"ConfTrackChoicePartOne", 1, "0:Proton, 1:Pion, 2:Kaon"}; ConfigurableAxis ConfTrkTempFitVarBins{"ConfTrkDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfTrkTempFitVarpTBins{"ConfTrkTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + // Configurable ConfChargePart1{"ConfChargePart1", 1, "sign of particle 1"}; // not used + Configurable ConfHPtPart1{"ConfHPtPart1", 4.0f, "higher limit for pt of particle 1"}; + Configurable ConfLPtPart1{"ConfLPtPart1", 0.3f, "lower limit for pt of particle 1"}; + Configurable Confmom{"Confmom", 0.5, "momentum threshold for particle identification using TOF"}; + Configurable ConfNsigmaTPCParticle{"ConfNsigmaTPCParticle", 3.0, "TPC Sigma for particle momentum < Confmom"}; + Configurable ConfNsigmaCombinedParticle{"ConfNsigmaCombinedParticle", 3.0, "TPC and TOF Sigma (combined) for particle momentum > Confmom"}; /// Partition for particle 1 - Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && ((aod::femtouniverseparticle::cut & ConfTrkCutPartOne) == ConfTrkCutPartOne); + // Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == ConfChargePart1 && aod::femtouniverseparticle::pt < ConfHPtPart1 && aod::femtouniverseparticle::pt > ConfLPtPart1; + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::pt < ConfHPtPart1 && aod::femtouniverseparticle::pt > ConfLPtPart1; /// Histogramming for particle 1 FemtoUniverseParticleHisto trackHistoPartOne; - /// Particle 2 (V0) - Configurable> ConfV0ChildrenCutTable{"ConfV0ChildrenCutTable", {cutsTableV0Children[0], nV0Children, nCuts, V0ChildrenName, cutNames}, "V0 Children selections"}; + /// Particle 2 (from V0) Configurable ConfV0PDGCodePartTwo{"ConfV0PDGCodePartTwo", 3122, "Particle 2 (V0) - PDG code"}; - Configurable ConfV0CutPartTwo{"ConfV0CutPartTwo", 338, "Particle 2 (V0) - Selection bit"}; ConfigurableAxis ConfV0TempFitVarBins{"ConfV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfV0TempFitVarpTBins{"ConfV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; - - Configurable ConfCutChildPos{"ConfCutChildPos", 150, "Positive Child of V0 - Selection bit from cutCulator"}; - Configurable ConfCutChildNeg{"ConfCutChildNeg", 149, "Negative Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildPosIndex{"ConfChildPosIndex", 1, "Positive Child of V0 - Index from cutCulator"}; - Configurable ConfChildNegIndex{"ConfChildNegIndex", 0, "Negative Child of V0 - Index from cutCulator"}; - Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child sel: Max. PID nSigma TPC"}; - Configurable ConfChildnSpecies{"ConfChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; + // Configurable ConfChildnSpecies{"ConfChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; // not used ConfigurableAxis ConfChildTempFitVarBins{"ConfChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfChildTempFitVarpTBins{"ConfChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; + Configurable ConfHPtPart2{"ConfHPtPart2", 4.0f, "higher limit for pt of particle 2"}; + Configurable ConfLPtPart2{"ConfLPtPart2", 0.3f, "lower limit for pt of particle 2"}; /// Partition for particle 2 - Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && ((aod::femtouniverseparticle::cut & ConfV0CutPartTwo) == ConfV0CutPartTwo); + Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && aod::femtouniverseparticle::pt < ConfHPtPart2 && aod::femtouniverseparticle::pt > ConfLPtPart2; /// Histogramming for particle 2 FemtoUniverseParticleHisto trackHistoPartTwo; @@ -97,10 +84,8 @@ struct femtoUniversePairTaskTrackV0 { /// Histogramming for Event FemtoUniverseEventHisto eventHisto; - int vPIDPartOne; - std::vector kNsigma; - /// Correlation part + // Configurable ConfTrackChoicePartTwo{"ConfTrackChoicePartTwo", 1, "0:Proton, 1:Pion, 2:Kaon"}; //not used Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; @@ -108,14 +93,13 @@ struct femtoUniversePairTaskTrackV0 { ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; - Configurable ConfNEventsMix{"ConfNEventsMix", 5, "Number of events for mixing"}; + // Configurable ConfNEventsMix{"ConfNEventsMix", 5, "Number of events for mixing"}; // not used Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; - 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)"}; @@ -127,29 +111,47 @@ struct femtoUniversePairTaskTrackV0 { HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; + bool IsParticleNSigma(float mom, float nsigmaTPCParticle, float nsigmaTOFParticle) + { + if (mom < Confmom) { + if (TMath::Abs(nsigmaTPCParticle) < ConfNsigmaTPCParticle) { + return true; + } else { + return false; + } + } else { + if (TMath::Hypot(nsigmaTOFParticle, nsigmaTPCParticle) < ConfNsigmaCombinedParticle) { + return true; + } else { + return false; + } + } + } + void init(InitContext&) { eventHisto.init(&qaRegistry); + qaRegistry.add("Tracks_one/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("Tracks_one/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); trackHistoPartOne.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfIsMC, ConfTrkPDGCodePartOne); trackHistoPartTwo.init(&qaRegistry, ConfV0TempFitVarpTBins, ConfV0TempFitVarBins, ConfIsMC, ConfV0PDGCodePartTwo); posChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, false); negChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, false); + // sameEventCont.setDeltaEta(-1.5, 1.5); sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfEtaBins, ConfPhiBins, ConfIsMC, ConfUse3D); sameEventCont.setPDGCodes(ConfTrkPDGCodePartOne, ConfV0PDGCodePartTwo); + // mixedEventCont.setDeltaEta(-1.5, 1.5); mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfEtaBins, ConfPhiBins, ConfIsMC, ConfUse3D); mixedEventCont.setPDGCodes(ConfTrkPDGCodePartOne, ConfV0PDGCodePartTwo); + pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); } - vPIDPartOne = ConfTrkPIDPartOne.value; - kNsigma = ConfTrkPIDnSigmaMax.value; } - /// This function processes the same event and takes care of all the histogramming - /// \todo the trivial loops over the tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... - void processSameEvent(o2::aod::FDCollision& col, o2::aod::FDParticles& parts) + void processSameEvent(o2::aod::FDCollision& col, FemtoFullParticles& parts) { const auto& magFieldTesla = col.magField(); @@ -160,42 +162,32 @@ struct femtoUniversePairTaskTrackV0 { eventHisto.fillQA(col); /// Histogramming same event - for (auto& part : groupPartsOne) { - if (part.p() > ConfTrkCutTable->get("Track", "MaxP") || part.pt() > ConfTrkCutTable->get("Track", "MaxPt") || - !isFullPIDSelected(part.pidcut(), part.p(), ConfTrkCutTable->get("Track", "PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfTrkCutTable->get("Track", "nSigmaTPC"), ConfTrkCutTable->get("Track", "nSigmaTPCTOF"))) { - continue; - } - trackHistoPartOne.fillQA(part); - } - for (auto& part : groupPartsTwo) { const auto& posChild = parts.iteratorAt(part.index() - 2); const auto& negChild = parts.iteratorAt(part.index() - 1); - // check cuts on V0 children - if (!((posChild.cut() & ConfCutChildPos) == ConfCutChildPos) || !((negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) || - !isFullPIDSelected(posChild.pidcut(), posChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPCTOF")) || - !isFullPIDSelected(negChild.pidcut(), negChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPCTOF"))) { - continue; - } + // printf("-- V0 d- %d d+ %d\n",negChild.globalIndex(),posChild.globalIndex()); + trackHistoPartTwo.fillQA(part); posChildHistos.fillQA(posChild); negChildHistos.fillQA(negChild); } - /// Now build the combinations - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (p1.p() > ConfTrkCutTable->get("Track", "MaxP") || p1.pt() > ConfTrkCutTable->get("Track", "MaxPt") || - !isFullPIDSelected(p1.pidcut(), p1.p(), ConfTrkCutTable->get("Track", "PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfTrkCutTable->get("Track", "nSigmaTPC"), ConfTrkCutTable->get("Track", "nSigmaTPCTOF"))) { - continue; - } - const auto& posChild = parts.iteratorAt(p2.index() - 2); - const auto& negChild = parts.iteratorAt(p2.index() - 1); - // check cuts on V0 children - if (!((posChild.cut() & ConfCutChildPos) == ConfCutChildPos) || !((negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) || - !isFullPIDSelected(posChild.pidcut(), posChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPCTOF")) || - !isFullPIDSelected(negChild.pidcut(), negChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPCTOF"))) { + for (auto& part : groupPartsOne) { + /// PID using stored binned nsigma + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + + if (!IsParticleNSigma(part.pt(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; } + qaRegistry.fill(HIST("Tracks_one/nSigmaTPC"), part.p(), tpcNSigmas[ConfTrackChoicePartOne]); + qaRegistry.fill(HIST("Tracks_one/nSigmaTOF"), part.p(), tofNSigmas[ConfTrackChoicePartOne]); + + trackHistoPartOne.fillQA(part); + } + + /// Now build the combinations + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { if (ConfIsCPR.value) { if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { continue; @@ -205,6 +197,13 @@ struct femtoUniversePairTaskTrackV0 { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + /// PID using stored binned nsigma + const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(p1.tofNSigmaStorePr()), unPackInTable(p1.tofNSigmaStorePi()), unPackInTable(p1.tofNSigmaStoreKa())}; + + if (!IsParticleNSigma(p1.pt(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + continue; + } sameEventCont.setPair(p1, p2, multCol, ConfUse3D); } } @@ -212,8 +211,7 @@ struct femtoUniversePairTaskTrackV0 { PROCESS_SWITCH(femtoUniversePairTaskTrackV0, processSameEvent, "Enable processing same event", true); /// This function processes the mixed event - /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... - void processMixedEvent(o2::aod::FDCollisions& cols, o2::aod::FDParticles& parts) + void processMixedEvent(o2::aod::FDCollisions& cols, FemtoFullParticles& parts) { ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; @@ -232,18 +230,6 @@ struct femtoUniversePairTaskTrackV0 { } for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (p1.p() > ConfTrkCutTable->get("Track", "MaxP") || p1.pt() > ConfTrkCutTable->get("Track", "MaxPt") || - !isFullPIDSelected(p1.pidcut(), p1.p(), ConfTrkCutTable->get("Track", "PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfTrkCutTable->get("Track", "nSigmaTPC"), ConfTrkCutTable->get("Track", "nSigmaTPCTOF"))) { - continue; - } - const auto& posChild = parts.iteratorAt(p2.index() - 2); - const auto& negChild = parts.iteratorAt(p2.index() - 1); - // check cuts on V0 children - if (!((posChild.cut() & ConfCutChildPos) == ConfCutChildPos) || !((negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) || - !isFullPIDSelected(posChild.pidcut(), posChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPCTOF")) || - !isFullPIDSelected(negChild.pidcut(), negChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPCTOF"))) { - continue; - } if (ConfIsCPR.value) { if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1)) { continue; @@ -253,6 +239,13 @@ struct femtoUniversePairTaskTrackV0 { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + /// PID using stored binned nsigma + const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(p1.tofNSigmaStorePr()), unPackInTable(p1.tofNSigmaStorePi()), unPackInTable(p1.tofNSigmaStoreKa())}; + + if (!IsParticleNSigma(p1.pt(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + continue; + } mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); } } diff --git a/PWGCF/Flow/Tasks/CMakeLists.txt b/PWGCF/Flow/Tasks/CMakeLists.txt index 997f5024e29..b6e1291b1f2 100644 --- a/PWGCF/Flow/Tasks/CMakeLists.txt +++ b/PWGCF/Flow/Tasks/CMakeLists.txt @@ -13,3 +13,9 @@ o2physics_add_dpl_workflow(flow-pt-efficiency SOURCES flowPtEfficiency.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flow-pbpb-task + SOURCES FlowPbPbTask.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) + diff --git a/PWGCF/Flow/Tasks/FlowPbPbTask.cxx b/PWGCF/Flow/Tasks/FlowPbPbTask.cxx new file mode 100644 index 00000000000..e5114c20774 --- /dev/null +++ b/PWGCF/Flow/Tasks/FlowPbPbTask.cxx @@ -0,0 +1,381 @@ +// 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/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/DataModel/EventSelection.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" + +#include "GFWPowerArray.h" +#include "GFW.h" +#include "GFWCumulant.h" +#include "FlowContainer.h" +#include "TList.h" +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +struct FlowPbPbTask { + + O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMin, float, 0.2f, "Minimal pT for poi tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMax, float, 10.0f, "Maximal pT for poi tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "Minimal pT for ref tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 3.0f, "Maximal pT for ref tracks") + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5, "Chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Use Nch for flow observables") + O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") + + ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; + ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; + 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.30, 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.20, 2.40, 2.60, 2.80, 3.00}, "pt axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "centrality axis for histograms"}; + + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); + + // Connect to ccdb + Service ccdb; + 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"}; + Configurable url{"ccdb-url", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + + // Define output + OutputObj fFC{FlowContainer("FlowContainer")}; + HistogramRegistry registry{"registry"}; + + // define global variables + GFW* fGFW = new GFW(); + std::vector corrconfigs; + TAxis* fPtAxis; + TRandom3* fRndm = new TRandom3(0); + std::vector>> BootstrapArray; + + using aodCollisions = soa::Filtered>; + using aodTracks = soa::Filtered>; + + void init(InitContext const&) + { + ccdb->setURL(url.value); + ccdb->setCaching(true); + ccdb->setCreatedNotAfter(nolaterthan.value); + + // Add some output objects to the histogram registry + registry.add("hPhi", "", {HistType::kTH1D, {axisPhi}}); + registry.add("hEta", "", {HistType::kTH1D, {axisEta}}); + registry.add("hPt", "", {HistType::kTH1D, {axisPtHist}}); + registry.add("hVtxZ", "", {HistType::kTH1D, {axisVertex}}); + registry.add("hMult", "", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); + registry.add("hCent", "", {HistType::kTH1D, {{90, 0, 90}}}); + registry.add("hMeanPt", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("hMeanPtWithinGap08", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("c22_gap08_Weff", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("c22_gap08_trackMeanPt", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("PtVariance_partA_WithinGap08", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("PtVariance_partB_WithinGap08", "", {HistType::kTProfile, {axisMultiplicity}}); + + // initial array + BootstrapArray.resize(cfgNbootstrap); + for (int i = 0; i < cfgNbootstrap; i++) { + // currently we have 5 TProfiles in each sub dir + BootstrapArray[i].resize(5); + } + for (int i = 0; i < cfgNbootstrap; i++) { + BootstrapArray[i][0] = std::get>(registry.add(Form("BootstrapContainer_%d/hMeanPtWithinGap08", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][1] = std::get>(registry.add(Form("BootstrapContainer_%d/c22_gap08_Weff", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][2] = std::get>(registry.add(Form("BootstrapContainer_%d/c22_gap08_trackMeanPt", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][3] = std::get>(registry.add(Form("BootstrapContainer_%d/PtVariance_partA_WithinGap08", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][4] = std::get>(registry.add(Form("BootstrapContainer_%d/PtVariance_partB_WithinGap08", i), "", {HistType::kTProfile, {axisMultiplicity}})); + } + + o2::framework::AxisSpec axis = axisPt; + int nPtBins = axis.binEdges.size() - 1; + double* PtBins = &(axis.binEdges)[0]; + fPtAxis = new TAxis(nPtBins, PtBins); + + // add in FlowContainer to Get boostrap sample automatically + TObjArray* oba = new TObjArray(); + oba->Add(new TNamed("ChGap22", "ChGap22")); + for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("ChGap22_pt_%i", i + 1), "ChGap22_pTDiff")); + oba->Add(new TNamed("ChFull22", "ChFull22")); + oba->Add(new TNamed("ChFull32", "ChFull32")); + oba->Add(new TNamed("ChFull42", "ChFull42")); + oba->Add(new TNamed("ChFull24", "ChFull24")); + oba->Add(new TNamed("ChFull26", "ChFull26")); + oba->Add(new TNamed("Ch04Gap22", "Ch04Gap22")); + oba->Add(new TNamed("Ch06Gap22", "Ch06Gap22")); + oba->Add(new TNamed("Ch08Gap22", "Ch08Gap22")); + oba->Add(new TNamed("Ch10Gap22", "Ch10Gap22")); + oba->Add(new TNamed("Ch04Gap32", "Ch04Gap32")); + oba->Add(new TNamed("Ch06Gap32", "Ch06Gap32")); + oba->Add(new TNamed("Ch08Gap32", "Ch08Gap32")); + oba->Add(new TNamed("Ch10Gap32", "Ch10Gap32")); + oba->Add(new TNamed("Ch04Gap42", "Ch04Gap42")); + oba->Add(new TNamed("Ch06Gap42", "Ch06Gap42")); + oba->Add(new TNamed("Ch08Gap42", "Ch08Gap42")); + oba->Add(new TNamed("Ch10Gap42", "Ch10Gap42")); + oba->Add(new TNamed("ChFull422", "ChFull422")); + oba->Add(new TNamed("Ch04GapA422", "Ch04GapA422")); + oba->Add(new TNamed("Ch04GapB422", "Ch04GapB422")); + oba->Add(new TNamed("Ch10GapA422", "Ch10GapA422")); + oba->Add(new TNamed("Ch10GapB422", "Ch10GapB422")); + oba->Add(new TNamed("ChFull3232", "ChFull3232")); + oba->Add(new TNamed("ChFull4242", "ChFull4242")); + oba->Add(new TNamed("Ch04Gap3232", "Ch04Gap3232")); + oba->Add(new TNamed("Ch04Gap4242", "Ch04Gap4242")); + oba->Add(new TNamed("Ch04Gap24", "Ch04Gap24")); + oba->Add(new TNamed("Ch10Gap3232", "Ch10Gap3232")); + oba->Add(new TNamed("Ch10Gap4242", "Ch10Gap4242")); + oba->Add(new TNamed("Ch10Gap24", "Ch10Gap24")); + fFC->SetName("FlowContainer"); + fFC->SetXAxis(fPtAxis); + fFC->Initialize(oba, axisMultiplicity, cfgNbootstrap); + delete oba; + + // eta region + fGFW->AddRegion("full", -0.8, 0.8, 1, 1); + 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 + fGFW->AddRegion("refP06", 0.3, 0.8, 1, 1); // gap6 positve region + fGFW->AddRegion("refN08", -0.8, -0.4, 1, 1); + 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("refN", -0.8, -0.4, 1, 1); + fGFW->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); + fGFW->AddRegion("olN", -0.8, -0.4, 1, 4); + + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {3 -3}", "ChFull32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 -4}", "ChFull42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 -2 -2}", "ChFull24", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 2 -2 -2 -2}", "ChFull26", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {2} refP04 {-2}", "Ch04Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN06 {2} refP06 {-2}", "Ch06Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ch08Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {2} refP10 {-2}", "Ch10Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {3} refP04 {-3}", "Ch04Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN06 {3} refP06 {-3}", "Ch06Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {3} refP08 {-3}", "Ch08Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {3} refP10 {-3}", "Ch10Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {4} refP04 {-4}", "Ch04Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN06 {4} refP06 {-4}", "Ch06Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {4} refP08 {-4}", "Ch08Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4} refP10 {-4}", "Ch10Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN {2} refP {-2}", "ChGap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN | olN {2} refP {-2}", "ChGap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 -2 -2}", "ChFull422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {-2 -2} refP04 {4}", "Ch04GapA422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {4} refP04 {-2 -2}", "Ch04GapB422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {-2 -2} refP10 {4}", "Ch10GapA422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4} refP10 {-2 -2}", "Ch10GapB422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {3 2 -3 -2}", "ChFull3232", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 2 -4 -2}", "ChFull4242", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {3 2} refP04 {-3 -2}", "Ch04Gap3232", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {4 2} refP04 {-4 -2}", "Ch04Gap4242", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {2 2} refP04 {-2 -2}", "Ch04Gap24", kFALSE)); + 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)); + fGFW->CreateRegions(); + } + + template + void FillProfile(const GFW::CorrConfig& corrconf, const ConstStr& tarName, const double& cent) + { + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + registry.fill(tarName, cent, val, dnx); + return; + } + return; + } + + template + void FillpTvnProfile(const GFW::CorrConfig& corrconf, const double& sum_pt, const double& WeffEvent, const ConstStr& vnWeff, const ConstStr& vnpT, const double& cent) + { + double meanPt = sum_pt / WeffEvent; + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) { + registry.fill(vnWeff, cent, val, dnx * WeffEvent); + registry.fill(vnpT, cent, val * meanPt, dnx * WeffEvent); + } + return; + } + return; + } + + void FillpTvnProfile(const GFW::CorrConfig& corrconf, const double& sum_pt, const double& WeffEvent, std::shared_ptr vnWeff, std::shared_ptr vnpT, const double& cent) + { + double meanPt = sum_pt / WeffEvent; + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) { + vnWeff->Fill(cent, val, dnx * WeffEvent); + vnpT->Fill(cent, val * meanPt, dnx * WeffEvent); + } + return; + } + return; + } + + void FillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) + { + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + return; + } + for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { + dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); + if (dnx == 0) + continue; + val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + } + return; + } + + void process(aodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, aodTracks const& tracks) + { + int Ntot = tracks.size(); + if (Ntot < 1) + return; + float l_Random = fRndm->Rndm(); + float vtxz = collision.posZ(); + registry.fill(HIST("hVtxZ"), vtxz); + registry.fill(HIST("hMult"), Ntot); + registry.fill(HIST("hCent"), collision.centFT0C()); + fGFW->Clear(); + const auto cent = collision.centFT0C(); + float weff = 1, wacc = 1; + double weffEvent = 0, waccEvent = 0; + int TrackNum = 0; + double ptSum = 0., ptSum_Gap08 = 0.; + double weffEvent_WithinGap08 = 0., weffEventSquare_WithinGap08 = 0.; + double sum_ptSquare_wSquare_WithinGap08 = 0., sum_pt_wSquare_WithinGap08 = 0.; + + for (auto& track : tracks) { + double pt = track.pt(); + double eta = track.eta(); + bool WithinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range + bool WithinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range + bool WithinEtaGap08 = (eta >= -0.4) && (eta <= 0.4); + if (WithinPtRef) { + registry.fill(HIST("hPhi"), track.phi()); + registry.fill(HIST("hEta"), track.eta()); + registry.fill(HIST("hPt"), pt); + weffEvent += weff; + waccEvent += wacc; + ptSum += weff * pt; + TrackNum++; + if (WithinEtaGap08) { + ptSum_Gap08 += weff * pt; + sum_pt_wSquare_WithinGap08 += weff * weff * pt; + sum_ptSquare_wSquare_WithinGap08 += weff * weff * pt * pt; + weffEvent_WithinGap08 += weff; + weffEventSquare_WithinGap08 += weff * weff; + } + } + if (WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 1); + if (WithinPtPOI) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 2); + if (WithinPtPOI && WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 4); + } + + double WeffEvent_diff_WithGap08 = weffEvent_WithinGap08 * weffEvent_WithinGap08 - weffEventSquare_WithinGap08; + // Filling TProfile + // MeanPt + registry.fill(HIST("hMeanPt"), cent, ptSum / weffEvent, weffEvent); + if (weffEvent_WithinGap08 > 1e-6) + registry.fill(HIST("hMeanPtWithinGap08"), cent, 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); + // PtVariance + if (WeffEvent_diff_WithGap08 > 1e-6) { + registry.fill(HIST("PtVariance_partA_WithinGap08"), cent, + (ptSum_Gap08 * ptSum_Gap08 - sum_ptSquare_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + registry.fill(HIST("PtVariance_partB_WithinGap08"), cent, + (weffEvent_WithinGap08 * ptSum_Gap08 - sum_pt_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + } + + // Filling Bootstrap Samples + int SampleIndex = static_cast(cfgNbootstrap * l_Random); + if (weffEvent_WithinGap08 > 1e-6) + BootstrapArray[SampleIndex][0]->Fill(cent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); + if (weffEvent_WithinGap08 > 1e-6) + FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, BootstrapArray[SampleIndex][1], BootstrapArray[SampleIndex][2], cent); + if (WeffEvent_diff_WithGap08 > 1e-6) { + BootstrapArray[SampleIndex][3]->Fill(cent, + (ptSum_Gap08 * ptSum_Gap08 - sum_ptSquare_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + BootstrapArray[SampleIndex][4]->Fill(cent, + (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); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index df2a4d02a60..8183ace5dd9 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -93,7 +93,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MultTPC_MultFT0C", "MultTPC vs MultFT0C", false, 400, 0, 800.0, VarManager::kMultTPC, 100, 0, 1000.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 1000.0, VarManager::kMultFT0A, 100, 0, 1000.0, VarManager::kMultFT0C); } - if (subGroupStr.Contains("multFTOPbPbRun3")) { + if (subGroupStr.Contains("ftmulpbpb")) { hm->AddHistogram(histClass, "MultTPC", "MultTPC", false, 100, 0.0, 50000.0, VarManager::kMultTPC); hm->AddHistogram(histClass, "MultFT0C", "MultFT0C", false, 100, 0.0, 60000.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "MultFT0A", "MultFT0A", false, 100, 0.0, 180000.0, VarManager::kMultFT0A); diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index 0cc7fc34bca..149e871a977 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -390,9 +390,9 @@ class V0PhotonCut : public TNamed // return false; // } - // if (track.x() > 82.9 && abs(track.y()) > abs(track.x() * TMath::Tan(10.f * TMath::DegToRad())) + 5.f) { - // return false; - // } + if (track.x() > 82.9 && abs(track.y()) > abs(track.x() * TMath::Tan(10.f * TMath::DegToRad())) + 5.f) { + return false; + } const float slope = TMath::Tan(2 * TMath::ATan(TMath::Exp(-0.5))); return !(track.x() > 82.9 && abs(track.y()) < 15.f && abs(abs(track.z()) - track.x() / slope) < 7.f && 15.f < abs(track.dcaXY())); diff --git a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx index 1cd2cd685a5..5eecb2d8a2a 100644 --- a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx +++ b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx @@ -274,7 +274,8 @@ struct PhotonConversionBuilder { auto track_par_cov = getTrackParCov(track); o2::base::Propagator::Instance()->propagateToX(track_par_cov, 83.f, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); trackiu_x = track_par_cov.getX(); - trackiu_y = track_par_cov.getY(); + // trackiu_y = track_par_cov.getY(); + trackiu_y = track.y(); trackiu_z = track_par_cov.getZ(); } else { trackiu_x = track.x(); @@ -323,13 +324,13 @@ struct PhotonConversionBuilder { gpu::gpustd::array dcaInfo; auto pTrack = getTrackPar(pos); - pTrack.setPID(o2::track::PID::Electron); + // pTrack.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, pTrack, 2.f, matCorr, &dcaInfo); auto posdcaXY = dcaInfo[0]; auto posdcaZ = dcaInfo[1]; auto nTrack = getTrackPar(ele); - nTrack.setPID(o2::track::PID::Electron); + // nTrack.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, nTrack, 2.f, matCorr, &dcaInfo); auto eledcaXY = dcaInfo[0]; auto eledcaZ = dcaInfo[1]; diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx index fc3b36d835a..0d1cf34a0c4 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx @@ -43,7 +43,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; @@ -223,7 +223,7 @@ struct MaterialBudget { continue; } - auto photons_coll = photons.sliceBy(perCollision, collision.collisionId()); + auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { for (auto& photon : photons_coll) { @@ -272,8 +272,8 @@ struct MaterialBudget { o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); double value[9] = {0.f}; float phi_cp1 = 0.f, eta_cp1 = 0.f; @@ -337,11 +337,11 @@ struct MaterialBudget { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); - auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.collisionId()); - auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.collisionId()); + auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); + auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); @@ -361,7 +361,7 @@ struct MaterialBudget { if (!IsSelectedPair(g1, g2, cut1, cut2)) { continue; } - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); for (auto& paircut : paircuts) { diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx index e00e2b6a655..50f50a861d1 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx @@ -230,7 +230,7 @@ struct MaterialBudgetMC { continue; } - auto photons_coll = photons.sliceBy(perCollision, collision.collisionId()); + auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { for (auto& photon : photons_coll) { @@ -298,8 +298,8 @@ struct MaterialBudgetMC { o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); double value[9] = {0.f}; float phi_cp1 = 0.f, eta_cp1 = 0.f; diff --git a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx index 5fb510613e5..05ea3174187 100644 --- a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx +++ b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx @@ -241,8 +241,8 @@ struct PhotonHBT { reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); if constexpr (pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) { for (auto& cut : cuts1) { @@ -324,11 +324,11 @@ struct PhotonHBT { THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); - auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.collisionId()); - auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.collisionId()); + auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); + auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); @@ -336,7 +336,7 @@ struct PhotonHBT { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx index faf20554f33..bf6a17708bf 100644 --- a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx +++ b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx @@ -513,8 +513,8 @@ struct Pi0EtaToGammaGamma { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); @@ -525,7 +525,7 @@ struct Pi0EtaToGammaGamma { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx index a411c4c1dc0..fc22b3a3283 100644 --- a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx +++ b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx @@ -256,8 +256,8 @@ struct TagAndProbe { reinterpret_cast(list_ev_pair->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); for (auto& g1 : photons1_coll) { @@ -334,11 +334,11 @@ struct TagAndProbe { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); - auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.collisionId()); - auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.collisionId()); + auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); + auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); @@ -357,7 +357,7 @@ struct TagAndProbe { } } for (auto& g2 : photons_coll2) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); for (auto& paircut : paircuts) { if (!paircut.IsSelected(g1, g2)) { diff --git a/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx b/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx index 6646f303633..ad7ed63220d 100644 --- a/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx +++ b/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx @@ -401,8 +401,8 @@ struct TaggingPi0 { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); @@ -413,7 +413,7 @@ struct TaggingPi0 { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx index 0295fe909b2..4a00e8f3953 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx @@ -62,6 +62,7 @@ struct Photon { { eta = eta_tmp; phi = phi_tmp; + onDCal = (phi < 6 && phi > 4); energy = energy_tmp; theta = 2 * std::atan2(std::exp(-eta), 1); px = energy * std::sin(theta) * std::cos(phi); @@ -79,6 +80,7 @@ struct Photon { float pz; float eta; float phi; + bool onDCal; // Checks whether photon is in phi region of the DCal, otherwise: EMCal float energy; float theta; int id; @@ -141,9 +143,13 @@ struct Pi0QCTask { Configurable mMinNCellsCut{"MinNCellsCut", 1, "apply min cluster number of cell cut"}; Configurable mMinOpenAngleCut{"OpeningAngleCut", 0.0202, "apply min opening angle cut"}; Configurable mClusterDefinition{"clusterDefinition", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; + Configurable mSplitEMCalDCal{"SplitEMCalDCal", 0, "Create and fill inv mass histograms for photons on EMCal and DCal individually"}; std::vector mVetoBCIDs; std::vector mSelectBCIDs; + ConfigurableAxis pTBinning{"pTBinning", {500, 0.0f, 50.0f}, "Binning used along pT axis for inv mass histograms"}; + ConfigurableAxis invmassBinning{"invmassBinning", {400, 0.0f, 0.8f}, "Binning used for inv mass axis in inv mass - pT histograms"}; + // define cluster filter. It selects only those clusters which are of the type // specified in the string mClusterDefinition,e.g. kV3Default, which is V3 clusterizer with default // clusterization parameters @@ -194,9 +200,18 @@ struct Pi0QCTask { mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100}}); // meson related histograms - mHistManager.add("invMassVsPt", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {{400, 0, 0.8}, {energyAxis}}); - mHistManager.add("invMassVsPtBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH2F, {{400, 0, 0.8}, {energyAxis}}); - mHistManager.add("invMassVsPtMixedBackground", "invariant mass and pT of mixed background meson candidates", o2HistType::kTH2F, {{400, 0, 0.8}, {energyAxis}}); + mHistManager.add("invMassVsPt", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtMixedBackground", "invariant mass and pT of mixed background meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + + if (mSplitEMCalDCal) { + mHistManager.add("invMassVsPt_EMCal", "invariant mass and pT of meson candidates with both clusters on EMCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground_EMCal", "invariant mass and pT of background meson candidates with both clusters on EMCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtMixedBackground_EMCal", "invariant mass and pT of mixed background meson candidates with both clusters on EMCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPt_DCal", "invariant mass and pT of meson candidates with both clusters on DCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground_DCal", "invariant mass and pT of background meson candidates with both clusters on DCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtMixedBackground_DCal", "invariant mass and pT of mixed background meson candidates with both clusters on DCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + } if (mVetoBCID->length()) { std::stringstream parser(mVetoBCID.value); @@ -228,10 +243,10 @@ struct Pi0QCTask { mHistManager.fill(HIST("eventsAll"), 1); LOG(debug) << "processCollisions"; // do event selection if mDoEventSel is specified - // currently the event selection is hard coded to kINT7 + // currently the event selection is hard coded to kTVXinEMC // but other selections are possible that are defined in TriggerAliases.h - if (mDoEventSel && (!collision.alias_bit(kINT7))) { - LOG(debug) << "Event not selected becaus it is not kINT7, skipping"; + if (mDoEventSel && (!collision.alias_bit(kTVXinEMC))) { + LOG(debug) << "Event not selected becaus it is not kTVXinEMC, skipping"; return; } mHistManager.fill(HIST("eventVertexZAll"), collision.posZ()); @@ -407,6 +422,14 @@ struct Pi0QCTask { Meson meson(mPhotons[ig1], mPhotons[ig2]); if (meson.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPt"), meson.getMass(), meson.getPt()); + + if (mSplitEMCalDCal) { + if (!mPhotons[ig1].onDCal && !mPhotons[ig2].onDCal) { + mHistManager.fill(HIST("invMassVsPt_EMCal"), meson.getMass(), meson.getPt()); + } else if (mPhotons[ig1].onDCal && mPhotons[ig2].onDCal) { + mHistManager.fill(HIST("invMassVsPt_DCal"), meson.getMass(), meson.getPt()); + } + } } // calculate background candidates (rotation background) @@ -457,9 +480,23 @@ struct Pi0QCTask { // Fill histograms if (mesonRotated1.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPtBackground"), mesonRotated1.getMass(), mesonRotated1.getPt()); + if (mSplitEMCalDCal) { + if (!mPhotons[ig1].onDCal && !mPhotons[ig2].onDCal && !mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_EMCal"), mesonRotated1.getMass(), mesonRotated1.getPt()); + } else if (mPhotons[ig1].onDCal && mPhotons[ig2].onDCal && mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_DCal"), mesonRotated1.getMass(), mesonRotated1.getPt()); + } + } } if (mesonRotated2.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPtBackground"), mesonRotated2.getMass(), mesonRotated2.getPt()); + if (mSplitEMCalDCal) { + if (!mPhotons[ig1].onDCal && !mPhotons[ig2].onDCal && !mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_EMCal"), mesonRotated2.getMass(), mesonRotated2.getPt()); + } else if (mPhotons[ig1].onDCal && mPhotons[ig2].onDCal && mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_DCal"), mesonRotated2.getMass(), mesonRotated2.getPt()); + } + } } } } @@ -471,6 +508,13 @@ struct Pi0QCTask { Meson meson(gamma, evtMix.vecEvtMix[i][ig1]); if (meson.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPtMixedBackground"), meson.getMass(), meson.getPt()); + if (mSplitEMCalDCal) { + if (!gamma.onDCal && !evtMix.vecEvtMix[i][ig1].onDCal) { + mHistManager.fill(HIST("invMassVsPtMixedBackground_EMCal"), meson.getMass(), meson.getPt()); + } else if (gamma.onDCal && evtMix.vecEvtMix[i][ig1].onDCal) { + mHistManager.fill(HIST("invMassVsPtMixedBackground_DCal"), meson.getMass(), meson.getPt()); + } + } } } } diff --git a/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx b/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx index b3e68613763..8c773a63d6e 100644 --- a/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx +++ b/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx @@ -35,7 +35,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using V0DatasAdditional = soa::Join; +using V0DatasAdditional = soa::Join; using V0LegsWithMC = soa::Join; // using collisionEvSelIt = soa::Join::iterator; @@ -608,7 +608,7 @@ struct GammaConversions { } } - Preslice perCollision = aod::v0photonkf::collisionId; + Preslice perCollision = aod::v0photonkf::emreducedeventId; void processRec(aod::EMReducedEvents::iterator const& theCollision, V0DatasAdditional const& theV0s, aod::V0Legs const& theAllTracks) @@ -617,7 +617,7 @@ struct GammaConversions { "hCollisionZ", theCollision.posZ()); - auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.collisionId()); + auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.globalIndex()); for (auto& lV0 : theV0s_per_coll) { float lV0CosinePA = lV0.cospa(); @@ -644,7 +644,7 @@ struct GammaConversions { "hCollisionZ", theCollision.posZ()); - auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.collisionId()); + auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.globalIndex()); for (auto& lV0 : theV0s) { float lV0CosinePA = lV0.cospa(); diff --git a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx index bebbcf202ee..2f43896b1de 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx @@ -154,7 +154,7 @@ struct PCMQC { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_after"))->Fill(collision.posZ()); o2::aod::emphotonhistograms::FillHistClass(list_ev, "", collision); - auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.collisionId()); + auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.globalIndex()); for (const auto& cut : fPCMCuts) { THashList* list_v0_cut = static_cast(list_v0->FindObject(cut.GetName())); THashList* list_v0leg_cut = static_cast(list_v0leg->FindObject(cut.GetName())); diff --git a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx index deacc5a0af1..c34d0d1bb30 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx @@ -160,7 +160,7 @@ struct PCMQCMC { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hCollisionCounter"))->Fill(4.0); reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_after"))->Fill(collision.posZ()); o2::aod::emphotonhistograms::FillHistClass(list_ev, "", collision); - auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.collisionId()); + auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.globalIndex()); for (const auto& cut : fPCMCuts) { THashList* list_v0_cut = static_cast(list_v0->FindObject(cut.GetName())); diff --git a/PWGHF/Core/HfMlResponseXicToPKPi.h b/PWGHF/Core/HfMlResponseXicToPKPi.h new file mode 100644 index 00000000000..82004e2eb36 --- /dev/null +++ b/PWGHF/Core/HfMlResponseXicToPKPi.h @@ -0,0 +1,187 @@ +// 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 HfMlResponseXicToPKPi.h +/// \brief Class to compute the ML response for Xic+ → p K- π+ (based on task for D± → π± K∓ π±) analysis selections +/// \author Cristina Terrevoli + +#ifndef PWGHF_CORE_HFMLRESPONSEXICTOPKPI_H_ +#define PWGHF_CORE_HFMLRESPONSEXICTOPKPI_H_ + +#include +#include +#include + +#include "PWGHF/Core/HfMlResponse.h" + +// Fill the map of available input features +// the key is the feature's name (std::string) +// the value is the corresponding value in EnumInputFeatures +#define FILL_MAP_XIC(FEATURE) \ + { \ +#FEATURE, static_cast < uint8_t>(InputFeaturesXicToPKPi::FEATURE) \ + } + +// Check if the index of mCachedIndices (index associated to a FEATURE) +// matches the entry in EnumInputFeatures associated to this FEATURE +// if so, the inputFeatures vector is filled with the FEATURE's value +// by calling the corresponding GETTER from OBJECT +#define CHECK_AND_FILL_VEC_XIC_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesXicToPKPi::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ + } + +// Specific case of CHECK_AND_FILL_VEC_XIC_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_XIC(GETTER) \ + case static_cast(InputFeaturesXicToPKPi::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + +namespace o2::analysis +{ +enum class InputFeaturesXicToPKPi : uint8_t { + ptProng0 = 0, + ptProng1, + ptProng2, + impactParameterXY0, + impactParameterXY1, + impactParameterXY2, + decayLength, + decayLengthXYNormalised, + cpa, + cpaXY, + tpcNSigmaP0, // 0 + tpcNSigmaKa0, // 0 + tpcNSigmaPi0, // 0 + tpcNSigmaP1, // 1 + tpcNSigmaKa1, // 1 + tpcNSigmaPi1, // 1 + tpcNSigmaP2, // 2 + tpcNSigmaKa2, // 2 + tpcNSigmaPi2, // 2 + tofNSigmaP0, // + tofNSigmaKa0, // + tofNSigmaPi0, // + tofNSigmaP1, + tofNSigmaKa1, + tofNSigmaPi1, + tofNSigmaP2, + tofNSigmaKa2, + tofNSigmaPi2 +}; + +template +class HfMlResponseXicToPKPi : public HfMlResponse +{ + public: + /// Default constructor + HfMlResponseXicToPKPi() = default; + /// Default destructor + virtual ~HfMlResponseXicToPKPi() = default; + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the Xic candidate + /// \param prong0 is the candidate's prong0 + /// \param prong1 is the candidate's prong1 + /// \param prong2 is the candidate's prong2 + /// \return inputFeatures vector + template + std::vector getInputFeatures(T1 const& candidate, + T2 const& prong0, T2 const& prong1, T2 const& prong2) + { + std::vector inputFeatures; + + for (const auto& idx : MlResponse::mCachedIndices) { + switch (idx) { + CHECK_AND_FILL_VEC_XIC(ptProng0); + CHECK_AND_FILL_VEC_XIC(ptProng1); + CHECK_AND_FILL_VEC_XIC(ptProng2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, impactParameterXY0, impactParameter0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, impactParameterXY1, impactParameter1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, impactParameterXY2, impactParameter2); + CHECK_AND_FILL_VEC_XIC(decayLength); + CHECK_AND_FILL_VEC_XIC(decayLengthXYNormalised); + CHECK_AND_FILL_VEC_XIC(cpa); + CHECK_AND_FILL_VEC_XIC(cpaXY); + // TPC PID variables + CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcNSigmaP0, tpcNSigmaPr); + CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcNSigmaKa0, tpcNSigmaKa); + CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcNSigmaPi0, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcNSigmaP1, tpcNSigmaPr); + CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcNSigmaKa1, tpcNSigmaKa); + CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcNSigmaPi1, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcNSigmaP2, tpcNSigmaPr); + CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcNSigmaKa2, tpcNSigmaKa); + CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcNSigmaPi2, tpcNSigmaPi); + // TOF PID variables + CHECK_AND_FILL_VEC_XIC_FULL(prong0, tofNSigmaP0, tofNSigmaPr); + CHECK_AND_FILL_VEC_XIC_FULL(prong0, tofNSigmaKa0, tofNSigmaKa); + CHECK_AND_FILL_VEC_XIC_FULL(prong0, tofNSigmaPi0, tofNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(prong1, tofNSigmaP1, tofNSigmaPr); + CHECK_AND_FILL_VEC_XIC_FULL(prong1, tofNSigmaKa1, tofNSigmaKa); + CHECK_AND_FILL_VEC_XIC_FULL(prong1, tofNSigmaPi1, tofNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(prong2, tofNSigmaP2, tofNSigmaPr); + CHECK_AND_FILL_VEC_XIC_FULL(prong2, tofNSigmaKa2, tofNSigmaKa); + CHECK_AND_FILL_VEC_XIC_FULL(prong2, tofNSigmaPi2, tofNSigmaPi); + } + } + + return inputFeatures; + } + + protected: + /// Method to fill the map of available input features + void setAvailableInputFeatures() + { + MlResponse::mAvailableInputFeatures = { + FILL_MAP_XIC(ptProng0), + FILL_MAP_XIC(ptProng1), + FILL_MAP_XIC(ptProng2), + FILL_MAP_XIC(impactParameterXY0), + FILL_MAP_XIC(impactParameterXY1), + FILL_MAP_XIC(impactParameterXY2), + FILL_MAP_XIC(decayLength), + FILL_MAP_XIC(decayLengthXYNormalised), + FILL_MAP_XIC(cpa), + FILL_MAP_XIC(cpaXY), + // TPC PID variables + FILL_MAP_XIC(tpcNSigmaP0), + FILL_MAP_XIC(tpcNSigmaKa0), + FILL_MAP_XIC(tpcNSigmaPi0), + FILL_MAP_XIC(tpcNSigmaP1), + FILL_MAP_XIC(tpcNSigmaKa1), + FILL_MAP_XIC(tpcNSigmaPi1), + FILL_MAP_XIC(tpcNSigmaP2), + FILL_MAP_XIC(tpcNSigmaKa2), + FILL_MAP_XIC(tpcNSigmaPi2), + // TOF PID variables + FILL_MAP_XIC(tofNSigmaP0), + FILL_MAP_XIC(tofNSigmaKa0), + FILL_MAP_XIC(tofNSigmaPi0), + FILL_MAP_XIC(tofNSigmaP1), + FILL_MAP_XIC(tofNSigmaKa1), + FILL_MAP_XIC(tofNSigmaPi1), + FILL_MAP_XIC(tofNSigmaP2), + FILL_MAP_XIC(tofNSigmaKa2), + FILL_MAP_XIC(tofNSigmaPi2)}; + } +}; + +} // namespace o2::analysis + +#undef FILL_MAP_XIC +#undef CHECK_AND_FILL_VEC_XIC_FULL +#undef CHECK_AND_FILL_VEC_XIC + +#endif // PWGHF_CORE_HFMLRESPONSEXICTOPKPI_H_ diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 873876f2ca4..8014da5a4a6 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -298,7 +298,7 @@ DECLARE_SOA_TABLE(HfMcGenRedB0s, "AOD", "HFMCGENREDB0", //! Generation-level MC // so we can use them in the B0 part namespace hf_cand_b0_config { -DECLARE_SOA_COLUMN(MySelectionFlagD, mySelectionFlagD, int8_t); //! Flag to filter selected D+ mesons +DECLARE_SOA_COLUMN(MySelectionFlagD, mySelectionFlagD, int8_t); //! Flag to filter selected D+ mesons DECLARE_SOA_COLUMN(MyInvMassWindowDPi, myInvMassWindowDPi, float); //! Half-width of the B0 invariant-mass window in GeV/c2 } // namespace hf_cand_b0_config diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index 1c2c2aad7f0..b24ef333c8d 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -271,10 +271,14 @@ namespace hf_sel_candidate_xic { DECLARE_SOA_COLUMN(IsSelXicToPKPi, isSelXicToPKPi, int); //! DECLARE_SOA_COLUMN(IsSelXicToPiKP, isSelXicToPiKP, int); //! +DECLARE_SOA_COLUMN(MlProbXicToPKPi, mlProbXicToPKPi, std::vector); //! +DECLARE_SOA_COLUMN(MlProbXicToPiKP, mlProbXicToPiKP, std::vector); //! } // namespace hf_sel_candidate_xic DECLARE_SOA_TABLE(HfSelXicToPKPi, "AOD", "HFSELXIC", //! hf_sel_candidate_xic::IsSelXicToPKPi, hf_sel_candidate_xic::IsSelXicToPiKP); +DECLARE_SOA_TABLE(HfMlXicToPKPi, "AOD", "HFMLXIC", //! + hf_sel_candidate_xic::MlProbXicToPKPi, hf_sel_candidate_xic::MlProbXicToPiKP); namespace hf_sel_candidate_xicc { diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index 0b2e582dfa4..14922bb4578 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -137,7 +137,7 @@ o2physics_add_dpl_workflow(candidate-selector-to-xi-pi o2physics_add_dpl_workflow(candidate-selector-xic-to-p-k-pi SOURCES candidateSelectorXicToPKPi.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(candidate-selector-xicc-to-p-k-pi-pi diff --git a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx index eca0dc9d5d0..dcf300d35a4 100644 --- a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx @@ -246,8 +246,8 @@ struct HfCandidateCreatorToXiPi { auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); for (const auto& trackIndexPion : groupedTrackIndices) { - // use bachelor selections from HfTrackIndexSkimCreatorTagSelTracks --> bit =2 is CandidateType::CandV0bachelor - if (!TESTBIT(trackIndexPion.isSelProng(), 2)) { + // use bachelor selections from HfTrackIndexSkimCreatorTagSelTracks --> bit = 4 is CandidateType::CandCascadeBachelor + if (!TESTBIT(trackIndexPion.isSelProng(), 4)) { continue; } diff --git a/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx b/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx index 65777de8ab6..7eee65c9530 100644 --- a/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx @@ -15,6 +15,7 @@ /// /// \author Mattia Faggin , University and INFN PADOVA /// \author Vít Kučera , CERN +/// \author Cristina Terrevoli , INFN BARI #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -22,7 +23,9 @@ #include "Common/Core/TrackSelectorPID.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseXicToPKPi.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -33,29 +36,47 @@ using namespace o2::framework; /// Struct for applying Xic selection cuts struct HfCandidateSelectorXicToPKPi { Produces hfSelXicToPKPiCandidate; + Produces hfMlXicToPKPiCandidate; Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; Configurable ptCandMax{"ptCandMax", 36., "Upper bound of candidate pT"}; Configurable usePid{"usePid", true, "Bool to use or not the PID at filtering level"}; // TPC PID Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Lower bound of track pT for TPC PID"}; - Configurable ptPidTpcMax{"ptPidTpcMax", 1., "Upper bound of track pT for TPC PID"}; + Configurable ptPidTpcMax{"ptPidTpcMax", 20., "Upper bound of track pT for TPC PID"}; Configurable nSigmaTpcMax{"nSigmaTpcMax", 3., "Nsigma cut on TPC only"}; Configurable nSigmaTpcCombinedMax{"nSigmaTpcCombinedMax", 5., "Nsigma cut on TPC combined with TOF"}; // TOF PID - Configurable ptPidTofMin{"ptPidTofMin", 0.5, "Lower bound of track pT for TOF PID"}; - Configurable ptPidTofMax{"ptPidTofMax", 4., "Upper bound of track pT for TOF PID"}; + Configurable ptPidTofMin{"ptPidTofMin", 0.15, "Lower bound of track pT for TOF PID"}; + Configurable ptPidTofMax{"ptPidTofMax", 20., "Upper bound of track pT for TOF PID"}; Configurable nSigmaTofMax{"nSigmaTofMax", 3., "Nsigma cut on TOF only"}; Configurable nSigmaTofCombinedMax{"nSigmaTofCombinedMax", 5., "Nsigma cut on TOF combined with TPC"}; // topological cuts Configurable decayLengthXYNormalisedMin{"decayLengthXYNormalisedMin", 3., "Min. normalised decay length XY"}; Configurable> binsPt{"binsPt", std::vector{hf_cuts_xic_to_p_k_pi::vecBinsPt}, "pT bin limits"}; Configurable> cuts{"cuts", {hf_cuts_xic_to_p_k_pi::cuts[0], hf_cuts_xic_to_p_k_pi::nBinsPt, hf_cuts_xic_to_p_k_pi::nCutVars, hf_cuts_xic_to_p_k_pi::labelsPt, hf_cuts_xic_to_p_k_pi::labelsCutVar}, "Xic candidate selection per pT bin"}; - - HfHelper hfHelper; + // ML inference + Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; + Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsMl{"cutsMl", {hf_cuts_ml::cuts[0], hf_cuts_ml::nBinsPt, hf_cuts_ml::nCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesMl{"nClassesMl", (int8_t)hf_cuts_ml::nCutScores, "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + // CCDB configuration + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTXic"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_XicToPKPi.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"}; + + o2::analysis::HfMlResponseXicToPKPi hfMlResponse; + std::vector outputMlXicToPKPi = {}; + std::vector outputMlXicToPiKP = {}; + o2::ccdb::CcdbApi ccdbApi; TrackSelectorPi selectorPion; TrackSelectorKa selectorKaon; TrackSelectorPr selectorProton; + HfHelper hfHelper; using TracksSel = soa::Join; @@ -69,6 +90,18 @@ struct HfCandidateSelectorXicToPKPi { selectorPion.setRangeNSigmaTofCondTpc(-nSigmaTofCombinedMax, nSigmaTofCombinedMax); selectorKaon = selectorPion; selectorProton = selectorPion; + + if (applyMl) { + hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } } /// Conjugate-independent topological cuts @@ -175,10 +208,20 @@ struct HfCandidateSelectorXicToPKPi { auto statusXicToPKPi = 0; auto statusXicToPiKP = 0; - if (!(candidate.hfflag() & 1 << aod::hf_cand_3prong::DecayType::XicToPKPi)) { + outputMlXicToPKPi.clear(); + outputMlXicToPiKP.clear(); + + if (!TESTBIT(candidate.hfflag(), aod::hf_cand_3prong::DecayType::XicToPKPi)) { hfSelXicToPKPiCandidate(statusXicToPKPi, statusXicToPiKP); + if (applyMl) { + hfMlXicToPKPiCandidate(outputMlXicToPKPi, outputMlXicToPiKP); + } continue; } + SETBIT(statusXicToPKPi, aod::SelectionStep::RecoSkims); + SETBIT(statusXicToPiKP, aod::SelectionStep::RecoSkims); + + auto ptCand = candidate.pt(); auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) @@ -189,6 +232,9 @@ struct HfCandidateSelectorXicToPKPi { // conjugate-independent topological selection if (!selectionTopol(candidate)) { hfSelXicToPKPiCandidate(statusXicToPKPi, statusXicToPiKP); + if (applyMl) { + hfMlXicToPKPiCandidate(outputMlXicToPKPi, outputMlXicToPiKP); + } continue; } @@ -199,8 +245,17 @@ struct HfCandidateSelectorXicToPKPi { if (!topolXicToPKPi && !topolXicToPiKP) { hfSelXicToPKPiCandidate(statusXicToPKPi, statusXicToPiKP); + if (applyMl) { + hfMlXicToPKPiCandidate(outputMlXicToPKPi, outputMlXicToPiKP); + } continue; } + if (topolXicToPKPi) { + SETBIT(statusXicToPKPi, aod::SelectionStep::RecoTopol); + } + if (topolXicToPiKP) { + SETBIT(statusXicToPiKP, aod::SelectionStep::RecoTopol); + } auto pidXicToPKPi = -1; auto pidXicToPiKP = -1; @@ -239,14 +294,46 @@ struct HfCandidateSelectorXicToPKPi { if (pidXicToPKPi == 0 && pidXicToPiKP == 0) { hfSelXicToPKPiCandidate(statusXicToPKPi, statusXicToPiKP); + if (applyMl) { + hfMlXicToPKPiCandidate(outputMlXicToPKPi, outputMlXicToPiKP); + } continue; } if ((pidXicToPKPi == -1 || pidXicToPKPi == 1) && topolXicToPKPi) { - statusXicToPKPi = 1; // identified as Xic->pKpi + SETBIT(statusXicToPKPi, aod::SelectionStep::RecoPID); } if ((pidXicToPiKP == -1 || pidXicToPiKP == 1) && topolXicToPiKP) { - statusXicToPiKP = 1; // identified as Xic->piKp + SETBIT(statusXicToPiKP, aod::SelectionStep::RecoPID); + } + + if (applyMl) { + // ML selections + bool isSelectedMlXicToPKPi = false; + bool isSelectedMlXicToPiKP = false; + + if (topolXicToPKPi && pidXicToPKPi) { + std::vector inputFeaturesXicToPKPi = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2); + isSelectedMlXicToPKPi = hfMlResponse.isSelectedMl(inputFeaturesXicToPKPi, ptCand, outputMlXicToPKPi); + } + if (topolXicToPiKP && pidXicToPiKP) { + std::vector inputFeaturesXicToPiKP = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2); + isSelectedMlXicToPiKP = hfMlResponse.isSelectedMl(inputFeaturesXicToPiKP, ptCand, outputMlXicToPiKP); + } + + hfMlXicToPKPiCandidate(outputMlXicToPKPi, outputMlXicToPiKP); + + if (!isSelectedMlXicToPKPi && !isSelectedMlXicToPiKP) { + hfSelXicToPKPiCandidate(statusXicToPKPi, statusXicToPiKP); + continue; + } + + if (isSelectedMlXicToPKPi) { + SETBIT(statusXicToPKPi, aod::SelectionStep::RecoMl); + } + if (isSelectedMlXicToPiKP) { + SETBIT(statusXicToPKPi, aod::SelectionStep::RecoMl); + } } hfSelXicToPKPiCandidate(statusXicToPKPi, statusXicToPiKP); diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 0f431da044a..dcc68082aa1 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -63,6 +63,7 @@ enum CandidateType { Cand3Prong, CandV0bachelor, CandDstar, + CandCascadeBachelor, NCandidateTypes }; @@ -364,11 +365,19 @@ struct HfTrackIndexSkimCreatorTagSelTracks { Configurable> cutsTrack3Prong{"cutsTrack3Prong", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for 3-prong candidates"}; Configurable etaMinTrack3Prong{"etaMinTrack3Prong", -99999., "min. pseudorapidity for 3 prong candidate"}; Configurable etaMaxTrack3Prong{"etaMaxTrack3Prong", 4., "max. pseudorapidity for 3 prong candidate"}; - // bachelor cuts (when using cascades) + // bachelor cuts (V0 + bachelor decays) Configurable ptMinTrackBach{"ptMinTrackBach", 0.3, "min. track pT for bachelor in cascade candidate"}; // 0.5 for PbPb 2015? Configurable> cutsTrackBach{"cutsTrackBach", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for the bachelor of V0-bachelor candidates"}; Configurable etaMinTrackBach{"etaMinTrackBach", -99999., "min. pseudorapidity for bachelor in cascade candidate"}; Configurable etaMaxTrackBach{"etaMaxTrackBach", 0.8, "max. pseudorapidity for bachelor in cascade candidate"}; + // bachelor cuts (cascade + bachelor decays) + Configurable ptMinTrackBachLfCasc{"ptMinTrackBachLfCasc", 0.1, "min. track pT for bachelor in cascade + bachelor decays"}; // 0.5 for PbPb 2015? + Configurable> cutsTrackBachLfCasc{"cutsTrackBachLfCasc", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for the bachelor in cascade + bachelor decays"}; + Configurable etaMinTrackBachLfCasc{"etaMinTrackBachLfCasc", -99999., "min. pseudorapidity for bachelor in cascade + bachelor decays"}; + Configurable etaMaxTrackBachLfCasc{"etaMaxTrackBachLfCasc", 1.1, "max. pseudorapidity for bachelor in cascade + bachelor decays"}; + Configurable useIsGlobalTrackForBachLfCasc{"useIsGlobalTrackForBachLfCasc", false, "check isGlobalTrack status for bachelor in cascade + bachelor decays"}; + Configurable useIsGlobalTrackWoDCAForBachLfCasc{"useIsGlobalTrackWoDCAForBachLfCasc", false, "check isGlobalTrackWoDCA status for bachelor in cascade + bachelor decays"}; + Configurable useIsQualityTrackITSForBachLfCasc{"useIsQualityTrackITSForBachLfCasc", true, "check isQualityTrackITS status for bachelor in cascade + bachelor decays"}; // soft pion cuts for D* Configurable ptMinSoftPionForDstar{"ptMinSoftPionForDstar", 0.05, "min. track pT for soft pion in D* candidate"}; Configurable ptMaxSoftPionForDstar{"ptMaxSoftPionForDstar", 2., "max. track pT for soft pion in D* candidate"}; @@ -413,7 +422,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { LOGP(fatal, "One and only one process function for the different PID selection strategies can be enabled at a time!"); } - cutsSingleTrack = {cutsTrack2Prong, cutsTrack3Prong, cutsTrackBach, cutsTrackDstar}; + cutsSingleTrack = {cutsTrack2Prong, cutsTrack3Prong, cutsTrackBach, cutsTrackDstar, cutsTrackBachLfCasc}; if (etaMinTrack2Prong == -99999.) { etaMinTrack2Prong.value = -etaMaxTrack2Prong; @@ -427,10 +436,13 @@ struct HfTrackIndexSkimCreatorTagSelTracks { if (etaMinSoftPionForDstar == -99999.) { etaMinSoftPionForDstar.value = -etaMaxSoftPionForDstar; } + if (etaMinTrackBachLfCasc == -99999.) { + etaMinTrackBachLfCasc.value = -etaMaxTrackBachLfCasc; + } if (fillHistograms) { // general tracks - registry.add("hRejTracks", "Tracks;;entries", {HistType::kTH1F, {{20, 0.5, 20.5}}}); + registry.add("hRejTracks", "Tracks;;entries", {HistType::kTH1F, {{25, 0.5, 25.5}}}); registry.add("hPtNoCuts", "all tracks;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); // 2-prong histograms @@ -441,7 +453,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.add("hPtCuts3Prong", "tracks selected for 3-prong vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); registry.add("hDCAToPrimXYVsPtCuts3Prong", "tracks selected for 3-prong vertexing;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); registry.add("hEtaCuts3Prong", "tracks selected for 3-prong vertexing;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxTrack3Prong - etaMinTrack3Prong) * 100), -1.2 * etaMinTrack3Prong, 1.2 * etaMaxTrack3Prong}}}); - // bachelor (for cascades) histograms + // bachelor (for V0 + bachelor decays) histograms registry.add("hPtCutsV0bachelor", "tracks selected for V0-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); registry.add("hDCAToPrimXYVsPtCutsV0bachelor", "tracks selected for V0-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); registry.add("hEtaCutsV0bachelor", "tracks selected for V0-bachelor vertexing;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxTrackBach - etaMinTrackBach) * 100), -1.2 * etaMinTrackBach, 1.2 * etaMaxTrackBach}}}); @@ -449,9 +461,13 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.add("hPtCutsSoftPionForDstar", "tracks selected for D* soft pion;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); registry.add("hDCAToPrimXYVsPtCutsSoftPionForDstar", "tracks selected for D* soft pion;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); registry.add("hEtaCutsSoftPionForDstar", "tracks selected for D* soft pion;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxSoftPionForDstar - etaMinSoftPionForDstar) * 100), -1.2 * etaMinSoftPionForDstar, 1.2 * etaMaxSoftPionForDstar}}}); + // bachelor (for cascade + bachelor decays) histograms + registry.add("hPtCutsCascadeBachelor", "tracks selected for cascade-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("hDCAToPrimXYVsPtCutsCascadeBachelor", "tracks selected for cascade-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); + registry.add("hEtaCutsCascadeBachelor", "tracks selected for cascade-bachelor vertexing;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxTrackBachLfCasc - etaMinTrackBachLfCasc) * 100), -1.2 * etaMinTrackBachLfCasc, 1.2 * etaMaxTrackBachLfCasc}}}); std::string cutNames[nCuts + 1] = {"selected", "rej pT", "rej eta", "rej track quality", "rej dca"}; - std::string candNames[CandidateType::NCandidateTypes] = {"2-prong", "3-prong", "bachelor", "dstar"}; + std::string candNames[CandidateType::NCandidateTypes] = {"2-prong", "3-prong", "bachelor", "dstar", "lfCascBachelor"}; for (int iCandType = 0; iCandType < CandidateType::NCandidateTypes; iCandType++) { for (int iCut = 0; iCut < nCuts + 1; iCut++) { registry.get(HIST("hRejTracks"))->GetXaxis()->SetBinLabel((nCuts + 1) * iCandType + iCut + 1, Form("%s %s", candNames[iCandType].data(), cutNames[iCut].data())); @@ -548,10 +564,10 @@ struct HfTrackIndexSkimCreatorTagSelTracks { return flag; } - /// Single-track cuts for 2-prongs, 3-prongs, or cascades + /// Single-track cuts for 2-prongs, 3-prongs, bachelor+V0, bachelor+cascade decays /// \param trackPt is the track pt /// \param dca is a 2-element array with dca in transverse and longitudinal directions - /// \param candType is the flag to decide which cuts to be applied (either for 2-prong, 3-prong, or cascade decays) + /// \param candType is the flag to decide which cuts to be applied (either for 2-prong, 3-prong, bachelor+V0 or bachelor+cascade decays) /// \return true if track passes all cuts bool isSelectedTrackDCA(const float& trackPt, const std::array& dca, const int candType) { @@ -609,6 +625,12 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandDstar + iCut); } } + if (trackPt < ptMinTrackBachLfCasc) { + CLRBIT(statusProng, CandidateType::CandCascadeBachelor); + if (fillHistograms) { + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } + } iCut = 3; // eta cut @@ -639,6 +661,13 @@ struct HfTrackIndexSkimCreatorTagSelTracks { } } + if (TESTBIT(statusProng, CandidateType::CandCascadeBachelor) && (trackEta > etaMaxTrackBachLfCasc || trackEta < etaMinTrackBachLfCasc)) { + CLRBIT(statusProng, CandidateType::CandCascadeBachelor); + if (fillHistograms) { + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } + } + // quality cut iCut = 4; bool hasGoodQuality = true; @@ -701,6 +730,35 @@ struct HfTrackIndexSkimCreatorTagSelTracks { } } + // quality cut for bachelor in cascade + bachelor decays + hasGoodQuality = true; + if (doCutQuality.value && TESTBIT(statusProng, CandidateType::CandCascadeBachelor)) { + if (useIsGlobalTrackForBachLfCasc) { + if (!hfTrack.isGlobalTrack()) { + hasGoodQuality = false; + } + } else if (useIsGlobalTrackWoDCAForBachLfCasc) { + if (!hfTrack.isGlobalTrackWoDCA()) { + hasGoodQuality = false; + } + } else if (useIsQualityTrackITSForBachLfCasc) { + if (!hfTrack.isQualityTrackITS()) { + hasGoodQuality = false; + } + } else { // selections for Run2 converted data + UChar_t clustermap = hfTrack.itsClusterMap(); + if (!(TESTBIT(hfTrack.flags(), o2::aod::track::ITSrefit) && (TESTBIT(clustermap, 0) || TESTBIT(clustermap, 1)))) { + hasGoodQuality = false; + } + } + if (!hasGoodQuality) { + CLRBIT(statusProng, CandidateType::CandCascadeBachelor); + if (fillHistograms) { + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } + } + } + // DCA cut iCut = 5; if (statusProng > 0) { @@ -741,6 +799,12 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.fill(HIST("hDCAToPrimXYVsPtCutsSoftPionForDstar"), trackPt, dca[0]); registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandDstar + iCut); } + if (TESTBIT(statusProng, CandidateType::CandCascadeBachelor)) { + registry.fill(HIST("hPtCutsCascadeBachelor"), trackPt); + registry.fill(HIST("hEtaCutsCascadeBachelor"), trackEta); + registry.fill(HIST("hDCAToPrimXYVsPtCutsCascadeBachelor"), trackPt, dca[0]); + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } } } @@ -3433,7 +3497,7 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag = 0; - if (!TESTBIT(trackIdPion1.isSelProng(), CandidateType::CandV0bachelor)) { + if (!TESTBIT(trackIdPion1.isSelProng(), CandidateType::CandCascadeBachelor)) { continue; } @@ -3529,7 +3593,7 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag = 0; - if (!TESTBIT(trackIdPion2.isSelProng(), CandidateType::CandV0bachelor)) { + if (!TESTBIT(trackIdPion2.isSelProng(), CandidateType::CandCascadeBachelor)) { continue; } diff --git a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx index 67022a16f09..b3bd0e93fa5 100644 --- a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx @@ -11,9 +11,10 @@ /// \file treeCreatorXicToPKPi.cxx /// \brief Writer of XiC -> pKpi candidates in the form of flat tables to be stored in TTrees. -/// inspired from file treeCreatorLcToPKPi.cxx +/// inspired from file treeCreatorLcToPKPi.cxx and to treeCreatorDplusToPiKPi.cxx /// \author Himanshu Sharma , INFN Padova +/// \author Cristina Terrevoli , INFN Bari #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -84,6 +85,47 @@ DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int); DECLARE_SOA_COLUMN(RunNumber, runNumber, int); } // namespace full +DECLARE_SOA_TABLE(HfCandXicLites, "AOD", "HFCANDXICLITE", + hf_cand::Chi2PCA, + full::DecayLength, + full::DecayLengthXY, + full::DecayLengthNormalised, + full::DecayLengthXYNormalised, + full::PtProng0, + full::PtProng1, + full::PtProng2, + hf_cand::ImpactParameter0, + hf_cand::ImpactParameter1, + hf_cand::ImpactParameter2, + full::NSigTpcPi0, + full::NSigTpcKa0, + full::NSigTpcPr0, + full::NSigTofPi0, + full::NSigTofKa0, + full::NSigTofPr0, + full::NSigTpcPi1, + full::NSigTpcKa1, + full::NSigTpcPr1, + full::NSigTofPi1, + full::NSigTofKa1, + full::NSigTofPr1, + full::NSigTpcPi2, + full::NSigTpcKa2, + full::NSigTpcPr2, + full::NSigTofPi2, + full::NSigTofKa2, + full::NSigTofPr2, + full::CandidateSelFlag, + full::M, + full::Pt, + full::Cpa, + full::CpaXY, + full::Eta, + full::Phi, + full::FlagMc, + full::OriginMcRec, + full::IsCandidateSwapped) + DECLARE_SOA_TABLE(HfCandXicFulls, "AOD", "HFCANDXICFULL", full::CollisionId, collision::PosX, @@ -186,8 +228,11 @@ struct HfTreeCreatorXicToPKPi { Produces rowCandidateFull; Produces rowCandidateFullEvents; Produces rowCandidateFullParticles; + Produces rowCandidateLite; - Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of candidates to store in the tree"}; + Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; + // parameters for production of training samples + Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; HfHelper hfHelper; @@ -218,7 +263,11 @@ struct HfTreeCreatorXicToPKPi { } // Filling candidate properties - rowCandidateFull.reserve(candidates.size()); + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(candidates.size()); + } else { + rowCandidateFull.reserve(candidates.size()); + } for (const auto& candidate : candidates) { auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) @@ -231,79 +280,122 @@ struct HfTreeCreatorXicToPKPi { float FunctionE) { double pseudoRndm = trackPos1.pt() * 1000. - (int64_t)(trackPos1.pt() * 1000); if (FunctionSelection >= 1 && pseudoRndm < downSampleBkgFactor) { - rowCandidateFull( - candidate.collisionId(), - candidate.posX(), - candidate.posY(), - candidate.posZ(), - candidate.xSecondaryVertex(), - candidate.ySecondaryVertex(), - candidate.zSecondaryVertex(), - candidate.errorDecayLength(), - candidate.errorDecayLengthXY(), - candidate.chi2PCA(), - candidate.rSecondaryVertex(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.impactParameterNormalised0(), - candidate.ptProng0(), - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - candidate.impactParameterNormalised1(), - candidate.ptProng1(), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), - candidate.impactParameterNormalised2(), - candidate.ptProng2(), - RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), - candidate.pxProng0(), - candidate.pyProng0(), - candidate.pzProng0(), - candidate.pxProng1(), - candidate.pyProng1(), - candidate.pzProng1(), - candidate.pxProng2(), - candidate.pyProng2(), - candidate.pzProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - candidate.errorImpactParameter0(), - candidate.errorImpactParameter1(), - candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.p(), - candidate.cpa(), - candidate.cpaXY(), - FunctionCt, - candidate.eta(), - candidate.phi(), - FunctionY, - FunctionE, - candidate.flagMcMatchRec(), - candidate.originMcRec(), - candidate.isCandidateSwapped(), - candidate.globalIndex()); + if (fillCandidateLiteTable) { + rowCandidateLite( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaKa(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaKa(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaPi(), + trackNeg.tpcNSigmaKa(), + trackNeg.tpcNSigmaPr(), + trackNeg.tofNSigmaPi(), + trackNeg.tofNSigmaKa(), + trackNeg.tofNSigmaPr(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaKa(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaKa(), + trackPos2.tofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.cpa(), + candidate.cpaXY(), + candidate.eta(), + candidate.phi(), + candidate.flagMcMatchRec(), + candidate.originMcRec(), + candidate.isCandidateSwapped()); + } else { + rowCandidateFull( + candidate.collisionId(), + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.rSecondaryVertex(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.impactParameterNormalised0(), + candidate.ptProng0(), + RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), + candidate.impactParameterNormalised1(), + candidate.ptProng1(), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.impactParameterNormalised2(), + candidate.ptProng2(), + RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaKa(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaKa(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaPi(), + trackNeg.tpcNSigmaKa(), + trackNeg.tpcNSigmaPr(), + trackNeg.tofNSigmaPi(), + trackNeg.tofNSigmaKa(), + trackNeg.tofNSigmaPr(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaKa(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaKa(), + trackPos2.tofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.p(), + candidate.cpa(), + candidate.cpaXY(), + FunctionCt, + candidate.eta(), + candidate.phi(), + FunctionY, + FunctionE, + candidate.flagMcMatchRec(), + candidate.originMcRec(), + candidate.isCandidateSwapped(), + candidate.globalIndex()); + } } }; @@ -350,7 +442,11 @@ struct HfTreeCreatorXicToPKPi { } // Filling candidate properties - rowCandidateFull.reserve(candidates.size()); + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(candidates.size()); + } else { + rowCandidateFull.reserve(candidates.size()); + } for (const auto& candidate : candidates) { auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) @@ -363,82 +459,124 @@ struct HfTreeCreatorXicToPKPi { float FunctionE) { double pseudoRndm = trackPos1.pt() * 1000. - (int64_t)(trackPos1.pt() * 1000); if (FunctionSelection >= 1 && pseudoRndm < downSampleBkgFactor) { - rowCandidateFull( - candidate.collisionId(), - candidate.posX(), - candidate.posY(), - candidate.posZ(), - candidate.xSecondaryVertex(), - candidate.ySecondaryVertex(), - candidate.zSecondaryVertex(), - candidate.errorDecayLength(), - candidate.errorDecayLengthXY(), - candidate.chi2PCA(), - candidate.rSecondaryVertex(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.impactParameterNormalised0(), - candidate.ptProng0(), - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - candidate.impactParameterNormalised1(), - candidate.ptProng1(), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), - candidate.impactParameterNormalised2(), - candidate.ptProng2(), - RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), - candidate.pxProng0(), - candidate.pyProng0(), - candidate.pzProng0(), - candidate.pxProng1(), - candidate.pyProng1(), - candidate.pzProng1(), - candidate.pxProng2(), - candidate.pyProng2(), - candidate.pzProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - candidate.errorImpactParameter0(), - candidate.errorImpactParameter1(), - candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.p(), - candidate.cpa(), - candidate.cpaXY(), - FunctionCt, - candidate.eta(), - candidate.phi(), - FunctionY, - FunctionE, - 0., - 0., - 0., - candidate.globalIndex()); + if (fillCandidateLiteTable) { + rowCandidateLite( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaKa(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaKa(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaPi(), + trackNeg.tpcNSigmaKa(), + trackNeg.tpcNSigmaPr(), + trackNeg.tofNSigmaPi(), + trackNeg.tofNSigmaKa(), + trackNeg.tofNSigmaPr(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaKa(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaKa(), + trackPos2.tofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.cpa(), + candidate.cpaXY(), + candidate.eta(), + candidate.phi(), + 0., + 0., + 0.); + } else { + rowCandidateFull( + candidate.collisionId(), + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.rSecondaryVertex(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.impactParameterNormalised0(), + candidate.ptProng0(), + RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), + candidate.impactParameterNormalised1(), + candidate.ptProng1(), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.impactParameterNormalised2(), + candidate.ptProng2(), + RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaKa(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaKa(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaPi(), + trackNeg.tpcNSigmaKa(), + trackNeg.tpcNSigmaPr(), + trackNeg.tofNSigmaPi(), + trackNeg.tofNSigmaKa(), + trackNeg.tofNSigmaPr(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaKa(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaKa(), + trackPos2.tofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.p(), + candidate.cpa(), + candidate.cpaXY(), + FunctionCt, + candidate.eta(), + candidate.phi(), + FunctionY, + FunctionE, + 0., + 0., + 0., + candidate.globalIndex()); + } } }; - fillTable(0, candidate.isSelXicToPKPi(), hfHelper.invMassXicToPKPi(candidate), hfHelper.ctXic(candidate), hfHelper.yXic(candidate), hfHelper.eXic(candidate)); fillTable(1, candidate.isSelXicToPiKP(), hfHelper.invMassXicToPiKP(candidate), hfHelper.ctXic(candidate), hfHelper.yXic(candidate), hfHelper.eXic(candidate)); } diff --git a/PWGJE/TableProducer/jettrackderived.cxx b/PWGJE/TableProducer/jettrackderived.cxx index 5fff4fcec48..923881c963b 100644 --- a/PWGJE/TableProducer/jettrackderived.cxx +++ b/PWGJE/TableProducer/jettrackderived.cxx @@ -109,6 +109,7 @@ struct jetspectraDerivedMaker { histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z with event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/sampledvertexz", "Sampled collsion Vertex Z with event (sel8) selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/NumContrib", "Number of contributors to vertex of collision; number of contributors to vtx; number of entries", HistType::kTH1F, {{nBins, 0, 600}}); + histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); const AxisSpec axisPercentileFT0A{binsPercentile, "Centrality FT0A"}; const AxisSpec axisPercentileFT0C{binsPercentile, "Centrality FT0C"}; @@ -128,80 +129,82 @@ struct jetspectraDerivedMaker { { // here we already fill some event histos for cross checks if (!collision.sel8()) { + histos.fill(HIST("EventProp/rejectedCollId"), 2); return false; } if (abs(collision.posZ()) > ValVtx) { + histos.fill(HIST("EventProp/rejectedCollId"), 3); return false; } histos.fill(HIST("EventProp/collisionVtxZ"), collision.posZ()); // test fill // Last thing, check the sampling if (fractionOfEvents < 1.f && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > fractionOfEvents) { // Skip events that are not sampled + histos.fill(HIST("EventProp/rejectedCollId"), 4); return false; } histos.fill(HIST("EventProp/sampledvertexz"), collision.posZ()); histos.fill(HIST("EventProp/NumContrib"), collision.numContrib()); - return true; - - if (fillMultiplicity) { - histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); + if (fillMultiplicity == true) { histos.fill(HIST("Centrality/FT0A"), collision.centFT0A()); - histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); + histos.fill(HIST("Centrality/FT0C"), collision.centFT0C()); + histos.fill(HIST("Mult/FT0C"), collision.multFT0C()); histos.fill(HIST("Mult/FT0A"), collision.multFT0A()); histos.fill(HIST("Mult/NTracksPV"), collision.multNTracksPV()); } + return true; } Produces tableTrack; using CollisionCandidate = soa::Join; using TrackCandidates = soa::Join; unsigned int randomSeed = 0; - void processData(CollisionCandidate::iterator const& collision, - TrackCandidates const& tracks, - aod::BCs const&) + void processData(CollisionCandidate const& collisions, + TrackCandidates const& tracks) { - if (!isEventSelected(collision)) { - return; + for (const auto& collision : collisions) { + if (!isEventSelected(collision)) { + histos.fill(HIST("EventProp/rejectedCollId"), 1); + } } + tableTrack.reserve(tracks.size()); for (const auto& trk : tracks) { - if (!trk.has_collision() || !(collision.globalIndex() == trk.collisionId())) { - return; - } - if (!customTrackCuts.IsSelected(trk)) { - return; + if (!customTrackCuts.IsSelected(trk)) { // we fill all tracks that have a collision(rejected or not) and pass this check ! + continue; + } else { + tableTrack(trk.collisionId(), + trk.trackTime(), + trk.signed1Pt(), trk.eta(), trk.phi(), trk.pt(), + trk.sigma1Pt(), + trk.alpha(), + trk.x(), trk.y(), trk.z(), + trk.snp(), + trk.tgl(), + trk.isPVContributor(), + trk.hasTRD(), + trk.hasITS(), + trk.hasTPC(), + trk.isGlobalTrack(), + trk.isGlobalTrackWoDCA(), + trk.isGlobalTrackWoPtEta(), + trk.flags(), + trk.trackType(), + trk.length(), + trk.tpcChi2NCl(), trk.itsChi2NCl(), trk.tofChi2(), + trk.tpcNClsShared(), + trk.tpcNClsFindable(), + trk.tpcNClsFindableMinusFound(), + trk.tpcNClsFindableMinusCrossedRows(), + trk.itsClusterMap(), + trk.itsNCls(), + trk.tpcFractionSharedCls(), + trk.tpcNClsFound(), + trk.tpcNClsCrossedRows(), + trk.tpcCrossedRowsOverFindableCls(), + trk.tpcFoundOverFindableCls(), + trk.dcaXY(), + trk.dcaZ()); } - tableTrack(trk.collisionId(), - trk.trackTime(), - trk.signed1Pt(), trk.eta(), trk.phi(), trk.pt(), - trk.sigma1Pt(), - trk.alpha(), - trk.x(), trk.y(), trk.z(), - trk.snp(), - trk.tgl(), - trk.isPVContributor(), - trk.hasTRD(), - trk.hasITS(), - trk.hasTPC(), - trk.isGlobalTrack(), - trk.isGlobalTrackWoDCA(), - trk.isGlobalTrackWoPtEta(), - trk.flags(), - trk.trackType(), - trk.length(), - trk.tpcChi2NCl(), trk.itsChi2NCl(), trk.tofChi2(), - trk.tpcNClsShared(), - trk.tpcNClsFindable(), - trk.tpcNClsFindableMinusFound(), - trk.tpcNClsFindableMinusCrossedRows(), - trk.itsClusterMap(), - trk.itsNCls(), - trk.tpcFractionSharedCls(), - trk.tpcNClsFound(), - trk.tpcNClsCrossedRows(), - trk.tpcCrossedRowsOverFindableCls(), - trk.tpcFoundOverFindableCls(), - trk.dcaXY(), - trk.dcaZ()); } } diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index 745ac543e91..6534cc97114 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -92,6 +92,10 @@ if(FastJet_FOUND) SOURCES trackJetqa.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-hadron-recoil + SOURCES jetHadronRecoil.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-nsubjettiness SOURCES nSubjettiness.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx new file mode 100644 index 00000000000..a4c886aa700 --- /dev/null +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -0,0 +1,179 @@ +// 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. + +// h+jet analysis task +// +// Authors: Daniel Jones + +#include +#include + +#include "TRandom3.h" + +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/runDataProcessing.h" +#include "EventFiltering/filterTables.h" + +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/DataModel/Jet.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct hJetAnalysis { + + Configurable pt_TTref_min{"pt_TTref_min", 5, "reference minimum trigger track pt"}; + Configurable pt_TTref_max{"pt_TTref_max", 7, "reference maximum trigger track pt"}; + Configurable pt_TTsig_min{"pt_TTsig_min", 20, "signal minimum trigger track pt"}; + Configurable pt_TTsig_max{"pt_TTsig_max", 50, "signal maximum trigger track pt"}; + Configurable frac_sig{"frac_sig", 0.5, "fraction of events to use for signal"}; + Configurable jetR{"jetR", 0.4, "jet resolution parameter"}; + + TRandom3* rand = new TRandom3(0); + + Filter jetCuts = aod::jet::r == nround(jetR.node() * 100.0f); + + HistogramRegistry registry{"registry", + {{"hNtrig", "number of triggers;trigger type;entries", {HistType::kTH1F, {{2, 0, 2}}}}, + {"hPtTrack", "Track p_{T};p_{T};entries", {HistType::kTH1F, {{100, 0, 100}}}}, + {"hEtaTrack", "Track #eta;#eta;entries", {HistType::kTH1F, {{20, -1, 1}}}}, + {"hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{200, -3.2, 6.4}}}}, + {"hReferencePtDPhi", "jet p_{T} vs DPhi;p_{T,jet};#Delta#phi", {HistType::kTH2F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}}}}, + {"hSignalPtDPhi", "jet p_{T} vs DPhi;p_{T,jet};#Delta#phi", {HistType::kTH2F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}}}}, + {"hReferencePt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{150, 0, 150}}}}, + {"hSignalPt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{150, 0, 150}}}}, + {"hSignalLeadingTrack", "leading track p_{T};p_{T,jet};#Delta#phi;leading track p_{T}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}, + {"hReferenceLeadingTrack", "leading track p_{T};p_{T,jet};#Delta#phi;leading track p_{T}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}, + {"hJetSignalMultiplicity", "jet multiplicity;N_{jets};entries", {HistType::kTH1F, {{10, 0, 10}}}}, + {"hJetReferenceMultiplicity", "jet multiplicity;N_{jets};entries", {HistType::kTH1F, {{10, 0, 10}}}}, + {"hJetSignalConstituentMultiplicity", "jet constituent multiplicity;p_{T,jet};#Delta#phi;N_{constituents}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {50, 0, 50}}}}, + {"hJetReferenceConstituentMultiplicity", "jet constituent multiplicity;p_{T,jet};#Delta#phi;N_{constituents}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {50, 0, 50}}}}, + {"hJetSignalConstituentPt", "jet constituent p_{T};p_{T,jet};#Delta#phi;p_{T,constituent}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}, + {"hJetReferenceConstituentPt", "jet constituent p_{T};p_{T,jet};#Delta#phi;p_{T,constituent}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}}}; + + void init(InitContext const&) {} + + float dPhi(float phi1, float phi2) + { + float dPhi = phi1 - phi2; + if (dPhi < -M_PI) + dPhi += 2 * M_PI; + if (dPhi > M_PI) + dPhi -= 2 * M_PI; + return dPhi; + } + + template + void fillHistograms(T const& jets, U const& tracks) + { + bool is_sig_col; + std::vector phi_TT_ar; + double phi_TT; + int trig_number; + int n_TT = 0; + double leadingPT = 0; + + float dice = rand->Rndm(); + if (dice < frac_sig) + is_sig_col = true; + else + is_sig_col = false; + + for (auto& track : tracks) { + if (is_sig_col && track.pt() < pt_TTsig_max && track.pt() > pt_TTsig_min) { + phi_TT_ar.push_back(track.phi()); + n_TT++; + } + if (!is_sig_col && track.pt() < pt_TTref_max && track.pt() > pt_TTref_min) { + phi_TT_ar.push_back(track.pt()); + n_TT++; + } + registry.fill(HIST("hPtTrack"), track.pt()); + registry.fill(HIST("hEtaTrack"), track.eta()); + registry.fill(HIST("hPhiTrack"), track.phi()); + } + + if (n_TT > 0) { + trig_number = rand->Integer(n_TT); + phi_TT = phi_TT_ar[trig_number]; + if (is_sig_col) { + registry.fill(HIST("hNtrig"), 1.5); + registry.fill(HIST("hJetSignalMultiplicity"), jets.size()); + } + if (!is_sig_col) { + registry.fill(HIST("hNtrig"), 0.5); + registry.fill(HIST("hJetReferenceMultiplicity"), jets.size()); + } + } + + for (auto& jet : jets) { + if (n_TT > 0) { + float dphi = dPhi(jet.phi(), phi_TT); + if (is_sig_col && std::abs(dphi) > M_PI - 0.6) { + registry.fill(HIST("hSignalPtDPhi"), jet.pt(), dphi); + registry.fill(HIST("hSignalPt"), jet.pt()); + registry.fill(HIST("hJetSignalConstituentMultiplicity"), jet.pt(), dphi, jet.tracks().size()); + for (auto& constituent : jet.template tracks_as()) { + if (constituent.pt() > leadingPT) { + leadingPT = constituent.pt(); + } + registry.fill(HIST("hJetSignalConstituentPt"), jet.pt(), dphi, constituent.pt()); + } + registry.fill(HIST("hSignalLeadingTrack"), jet.pt(), dphi, leadingPT); + } + if (!is_sig_col && std::abs(dphi) > M_PI - 0.6) { + registry.fill(HIST("hReferencePtDPhi"), jet.pt(), dphi); + registry.fill(HIST("hReferencePt"), jet.pt()); + registry.fill(HIST("hJetReferenceConstituentMultiplicity"), jet.pt(), dphi, jet.tracks().size()); + for (auto& constituent : jet.template tracks_as()) { + if (constituent.pt() > leadingPT) { + leadingPT = constituent.pt(); + } + registry.fill(HIST("hJetReferenceConstituentPt"), jet.pt(), dphi, constituent.pt()); + } + registry.fill(HIST("hReferenceLeadingTrack"), jet.pt(), dphi, leadingPT); + } + } + } + } + + void processData(aod::JCollision const&, soa::Filtered> const& jets, aod::JTracks const& tracks) + { + fillHistograms(jets, tracks); + } + PROCESS_SWITCH(hJetAnalysis, processData, "process data", true); + + void processMCD(aod::JCollision const&, soa::Filtered> const& jets, aod::JTracks const& tracks) + { + fillHistograms(jets, tracks); + } + PROCESS_SWITCH(hJetAnalysis, processMCD, "process MC detector level", false); + + void processMCP(aod::JMcCollision const&, soa::Filtered> const& jets, aod::JMcParticles const& particles) + { + fillHistograms(jets, particles); + } + PROCESS_SWITCH(hJetAnalysis, processMCP, "process MC particle level", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"hJetAnalysis"})}; } diff --git a/PWGJE/Tasks/trackJetqa.cxx b/PWGJE/Tasks/trackJetqa.cxx index 64aed5deb96..f13a87dd4a9 100644 --- a/PWGJE/Tasks/trackJetqa.cxx +++ b/PWGJE/Tasks/trackJetqa.cxx @@ -144,6 +144,8 @@ struct TrackJetQa { histos.add("EventProp/collisionVtxZ", "Collsion Vertex Z;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/collisionVtxZnoSel", "Collsion Vertex Z without event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z with event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); + histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); + // Common axes const AxisSpec axisPercentileFT0M{binsPercentile, "Centrality FT0M"}; const AxisSpec axisPercentileFT0A{binsPercentile, "Centrality FT0A"}; @@ -187,16 +189,18 @@ struct TrackJetQa { } template - void fillEventQa(eventInfo const& collision) + bool fillEventQa(eventInfo const& collision) { // fill event property variables histos.fill(HIST("EventProp/collisionVtxZnoSel"), collision.posZ()); if (!collision.sel8()) { - return; + histos.fill(HIST("EventProp/rejectedCollId"), 2); + return false; } histos.fill(HIST("EventProp/collisionVtxZSel8"), collision.posZ()); if (fabs(collision.posZ()) > ValVtx) { - return; + histos.fill(HIST("EventProp/rejectedCollId"), 3); + return false; } histos.fill(HIST("EventProp/collisionVtxZ"), collision.posZ()); if (fillMultiplicity) { @@ -206,23 +210,24 @@ struct TrackJetQa { histos.fill(HIST("Mult/FT0A"), collision.multFT0A()); histos.fill(HIST("Mult/FT0C"), collision.multFT0C()); } + return true; } template - void fillTrackQa(Tracks const& track) + bool fillTrackQa(Tracks const& track) { // check track selection if ((globalTrack == true) && (!track.isGlobalTrack())) { - return; + return false; } if ((globalTrackWoDCA == true) && (!track.isGlobalTrackWoDCA())) { - return; + return false; } if ((globalTrackWoPtEta == true) && (!track.isGlobalTrackWoPtEta())) { - return; + return false; } if ((customTrack == true) && (!customTrackCuts.IsSelected(track))) { - return; + return false; } // fill kinematic variables histos.fill(HIST("Kine/pt"), track.pt()); @@ -306,29 +311,41 @@ struct TrackJetQa { histos.fill(HIST("TPC/tpcCrossedRowsOverFindableCls"), track.pt(), track.tpcCrossedRowsOverFindableCls()); histos.fill(HIST("TPC/tpcFractionSharedCls"), track.pt(), track.tpcFractionSharedCls()); histos.fill(HIST("TPC/tpcChi2NCl"), track.pt(), track.tpcChi2NCl()); + + return true; } // Preslice> trackPerColl = aod::track::collisionId; Preslice trackPerColl = aod::track::collisionId; // SliceCache cacheTrk; - void processFull(soa::Join const& collisions, - soa::Join const& tracks) + using CollisionCandidate = soa::Join; + using TrackCandidates = soa::Join; + + void processFull(CollisionCandidate const& collisions, + TrackCandidates const& tracks) { for (const auto& collision : collisions) { - fillEventQa(collision); - if (fillMultiplicity) { - histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); - histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); - histos.fill(HIST("Mult/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); - } - auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); + if (fillEventQa(collision)) { - for (const auto& track : tracksInCollision) { - fillTrackQa(track); if (fillMultiplicity) { - histos.fill(HIST("TrackEventPar/Sigma1PtFT0Mcent"), collision.centFT0M(), track.pt(), track.sigma1Pt()); - histos.fill(HIST("TrackEventPar/MultCorrelations"), track.sigma1Pt(), track.pt(), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); + histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); + histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); + histos.fill(HIST("Mult/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); + } + auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); + + for (const auto& track : tracksInCollision) { + if (track.has_collision() && (collision.globalIndex() == track.collisionId())) { // double check + if (fillTrackQa(track)) { + if (fillMultiplicity) { + histos.fill(HIST("TrackEventPar/Sigma1PtFT0Mcent"), collision.centFT0M(), track.pt(), track.sigma1Pt()); + histos.fill(HIST("TrackEventPar/MultCorrelations"), track.sigma1Pt(), track.pt(), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); + } + } + } } + } else { + histos.fill(HIST("EventProp/rejectedCollId"), 1); } } } diff --git a/PWGLF/DataModel/QC/strangenessTablesQC.h b/PWGLF/DataModel/QC/strangenessTablesQC.h new file mode 100644 index 00000000000..042fbd3f2be --- /dev/null +++ b/PWGLF/DataModel/QC/strangenessTablesQC.h @@ -0,0 +1,119 @@ +// 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 QA task for Cascade analysis using derived data +/// +/// \author Roman Nepeivoda (roman.nepeivoda@cern.ch) + +#ifndef PWGLF_DATAMODEL_STRANGENESSTABLESQC_H_ +#define PWGLF_DATAMODEL_STRANGENESSTABLESQC_H_ + +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace o2::aod +{ +namespace cascadesQC +{ +DECLARE_SOA_COLUMN(CascCosPA, casccosPA, float); //! +DECLARE_SOA_COLUMN(V0CosPA, v0cosPA, float); //! needs to be changed to double +DECLARE_SOA_COLUMN(CascRadius, cascradius, float); //! +DECLARE_SOA_COLUMN(V0Radius, v0radius, float); //! V0 decay radius (2D, centered at zero) +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(YXi, yXi, float); //! +DECLARE_SOA_COLUMN(YOmega, yOmega, float); //! +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! cascade decay length +DECLARE_SOA_COLUMN(LifetimeXi, lifetimeXi, float); //! +DECLARE_SOA_COLUMN(LifetimeOmega, lifetimeOmega, float); //! +DECLARE_SOA_COLUMN(LifetimeV0, lifetimeV0, float); //! +DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! DCA between V0 daughters +DECLARE_SOA_COLUMN(DCACascDaughters, dcacascdaughters, float); //! +DECLARE_SOA_COLUMN(DCAV0toPV, dcav0topv, float); //! +DECLARE_SOA_COLUMN(DCAbachtoPV, dcabachtopv, float); //! +DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! DCA positive prong to PV +DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! DCA negative prong to PV +DECLARE_SOA_COLUMN(PosNSigmaV0Pion, posNSigmaV0Pion, float); //! +DECLARE_SOA_COLUMN(PosNSigmaV0Proton, posNSigmaV0Proton, float); //! +DECLARE_SOA_COLUMN(NegNSigmaV0Pion, negNSigmaV0Pion, float); //! +DECLARE_SOA_COLUMN(NegNSigmaV0Proton, negNSigmaV0Proton, float); //! +DECLARE_SOA_COLUMN(BachNSigmaV0Pion, bachNSigmaV0Pion, float); //! +DECLARE_SOA_COLUMN(BachNSigmaV0Kaon, bachNSigmaV0Kaon, float); //! +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! +DECLARE_SOA_COLUMN(MOmega, mOmega, float); //! +DECLARE_SOA_COLUMN(MXi, mXi, float); //! + +} // namespace cascadesQC + +DECLARE_SOA_TABLE(CascadesQC, "AOD", "CASCADESQC", o2::soa::Index<>, + cascadesQC::Sign, cascadesQC::YXi, cascadesQC::YOmega, + cascadesQC::CascCosPA, cascadesQC::V0CosPA, + cascadesQC::CascRadius, cascadesQC::V0Radius, + cascadesQC::DecayLength, cascadesQC::LifetimeXi, cascadesQC::LifetimeOmega, cascadesQC::LifetimeV0, + cascadesQC::DCAV0Daughters, cascadesQC::DCACascDaughters, cascadesQC::DCAV0toPV, + cascadesQC::DCAbachtoPV, cascadesQC::DCAPosToPV, cascadesQC::DCANegToPV, + cascadesQC::PosNSigmaV0Pion, cascadesQC::PosNSigmaV0Proton, + cascadesQC::NegNSigmaV0Pion, cascadesQC::NegNSigmaV0Proton, + cascadesQC::BachNSigmaV0Pion, cascadesQC::BachNSigmaV0Kaon, + cascadesQC::Pt, cascadesQC::Eta, + cascadesQC::MLambda, cascadesQC::MOmega, cascadesQC::MXi); + +namespace vZerosQC +{ +DECLARE_SOA_COLUMN(V0CosPA, v0cosPA, float); //! needs to be changed to double +DECLARE_SOA_COLUMN(YK0Short, yK0Short, float); //! V0 y with K0short hypothesis +DECLARE_SOA_COLUMN(YLambda, yLambda, float); //! V0 y with lambda or antilambda hypothesis +DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! DCA between V0 daughters +DECLARE_SOA_COLUMN(DCAV0toPV, dcav0topv, float); //! DCA V0 to PV +DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! DCA positive prong to PV +DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! DCA negative prong to PV +DECLARE_SOA_COLUMN(V0Radius, v0radius, float); //! V0 decay radius (2D, centered at zero) +DECLARE_SOA_COLUMN(PosNSigmaV0Pion, posNSigmaV0Pion, float); //! number of TPC sigmas for a pos daughter to be a pion +DECLARE_SOA_COLUMN(PosNSigmaV0Proton, posNSigmaV0Proton, float); //! number of TPC sigmas for a pos daughter to be a proton +DECLARE_SOA_COLUMN(NegNSigmaV0Pion, negNSigmaV0Pion, float); //! number of TPC sigmas for a neg daughter to be a pion +DECLARE_SOA_COLUMN(NegNSigmaV0Proton, negNSigmaV0Proton, float); //! number of TPC sigmas for a neg daughter to be a proton +DECLARE_SOA_COLUMN(LifetimeLambda, lifetimeLambda, float); //! lifetime with lambda mass assumption +DECLARE_SOA_COLUMN(LifetimeK0s, lifetimeK0s, float); //! lifetime with K0s mass assumption +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! V0 decay length +DECLARE_SOA_COLUMN(PosITSNhits, posITSNhits, int); //! number of ITS hits of pos daughter +DECLARE_SOA_COLUMN(NegITSNhits, negITSNhits, int); //! number of ITS hits of neg daughter +DECLARE_SOA_COLUMN(Pt, pt, float); //! transverse momentum in GeV/c +DECLARE_SOA_COLUMN(Eta, eta, float); //! pseudorapidity of V0 +DECLARE_SOA_COLUMN(PosEta, poseta, float); //! pseudorapidity of V0 pos daughter +DECLARE_SOA_COLUMN(NegEta, negeta, float); //! pseudorapidity of V0 neg daughter +DECLARE_SOA_COLUMN(PosPhi, posphi, float); //! +DECLARE_SOA_COLUMN(NegPhi, negphi, float); //! +DECLARE_SOA_COLUMN(MK0Short, mK0Short, float); //! inv mass with K0s assumption +DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! inv mass with lambda assumption +DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! inv mass with anti-lambda assumption +} // namespace vZerosQC + +DECLARE_SOA_TABLE(VZerosQC, "AOD", "VZEROSQC", o2::soa::Index<>, + vZerosQC::YK0Short, vZerosQC::YLambda, + vZerosQC::DCAV0Daughters, vZerosQC::DCAV0toPV, + vZerosQC::DCAPosToPV, vZerosQC::DCANegToPV, + vZerosQC::V0Radius, vZerosQC::V0CosPA, + vZerosQC::PosNSigmaV0Pion, vZerosQC::PosNSigmaV0Proton, + vZerosQC::NegNSigmaV0Pion, vZerosQC::NegNSigmaV0Proton, + vZerosQC::DecayLength, vZerosQC::LifetimeLambda, vZerosQC::LifetimeK0s, + vZerosQC::PosITSNhits, vZerosQC::NegITSNhits, + vZerosQC::Pt, vZerosQC::Eta, + vZerosQC::MK0Short, vZerosQC::MLambda, vZerosQC::MAntiLambda, + vZerosQC::PosEta, vZerosQC::NegEta, + vZerosQC::PosPhi, vZerosQC::NegPhi); +} // namespace o2::aod + +#endif // PWGLF_DATAMODEL_STRANGENESSTABLESQC_H_ diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index 34078a45cf4..e5c2e28f318 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -9,6 +9,8 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. +add_subdirectory(QC) + # General purpose o2physics_add_dpl_workflow(tpcpid SOURCES lfTPCPID.cxx @@ -16,6 +18,7 @@ o2physics_add_dpl_workflow(tpcpid COMPONENT_NAME Analysis) # Strangeness + o2physics_add_dpl_workflow(lambdakzerobuilder SOURCES lambdakzerobuilder.cxx PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore diff --git a/PWGLF/TableProducer/QC/CMakeLists.txt b/PWGLF/TableProducer/QC/CMakeLists.txt new file mode 100644 index 00000000000..f8e4e1bcdd6 --- /dev/null +++ b/PWGLF/TableProducer/QC/CMakeLists.txt @@ -0,0 +1,15 @@ +# 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. + +o2physics_add_dpl_workflow(strangenessqc + SOURCES strangenessQC.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/TableProducer/QC/strangenessQC.cxx b/PWGLF/TableProducer/QC/strangenessQC.cxx new file mode 100644 index 00000000000..ad0875357e0 --- /dev/null +++ b/PWGLF/TableProducer/QC/strangenessQC.cxx @@ -0,0 +1,241 @@ +// 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 V0 and Cascade derived table producer for strangeness in pb-pb QC task +/// +/// In case of questions please write to: +/// \author Roman Nepeivoda (roman.nepeivoda@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/PIDResponse.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/QC/strangenessTablesQC.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct strangenessQC { + // Tables to produce + Produces cascadesQC; + Produces vZerosQC; + + // Histogram registries + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rGeneral{"generalInfo", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable sel8{"sel8", true, "Apply sel8 event selection"}; + + // Configurable parameters for V0 selection + Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"}; + Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1, "DCA Pos To PV"}; + Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1, "DCA Neg To PV"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.97, "V0 CosPA"}; // should be double! + Configurable v0setting_radius{"v0setting_radius", 1, "v0radius"}; + Configurable v0setting_rapidity{"v0setting_rapidity", 0.5, "rapidity"}; + + // Configurable parameters for cascade selection + Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.98, "Casc CosPA"}; // should be double! + Configurable cascadesetting_v0cospa{"cascadesetting_v0cospa", 0.98, "Casc V0 CosPA"}; // should be double! + Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable cascadesetting_dcav0dau{"cascadesetting_dcav0dau", 1.0, "DCA Cascade's V0 Daughters"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.1, "DCA bachelor to PV"}; + Configurable cascadesetting_dcapostopv{"cascadesetting_dcapostopv", 0.2, "DCA Casc. V0's pos to PV"}; + Configurable cascadesetting_dcanegtopv{"cascadesetting_dcanegtopv", 0.2, "DCA Casc V0's neg to PV"}; + Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "minimum V0 DCA to PV"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 1.0, "cascradius"}; + Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "v0 mass window"}; + Configurable cascadesetting_v0radius{"cascadesetting_v0radius", 0.9, "v0 radius"}; + Configurable cascadesetting_rapidity{"cascadesetting_rapidity", 0.5, "rapidity"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec vertexZAxis = {100, -15., 15., "vrtx_{Z} [cm]"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + + // Cut summary + rGeneral.add("selectionSummary", "selectionSummary", HistType::kTH1F, {{19, -0.5, 18.5}}); + TString CutLabelSummary[19] = {"cutzvertex", "v0_dcav0dau", "v0_dcapostopv", "v0_dcanegtopv", "v0_cospa", "v0_radius", "v0_rapidity", + "casc_cospa", "casc_v0cospa", "casc_dcacascdau", "casc_dcav0dau", "casc_dcabachtopv", "casc_dcapostopv", "casc_dcanegtopv", "casc_mindcav0topv", "casc_cascradius", "casc_v0masswindow", "casc_v0radius", "casc_rapidity"}; + for (Int_t n = 1; n <= rGeneral.get(HIST("selectionSummary"))->GetNbinsX(); n++) { + rGeneral.get(HIST("selectionSummary"))->GetXaxis()->SetBinLabel(n, CutLabelSummary[n - 1]); + } + rGeneral.get(HIST("selectionSummary"))->SetBinContent(1, cutzvertex); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(2, v0setting_dcav0dau); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(3, v0setting_dcapostopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(4, v0setting_dcanegtopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(5, v0setting_cospa); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(6, v0setting_radius); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(7, v0setting_rapidity); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(8, cascadesetting_cospa); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(9, cascadesetting_v0cospa); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(10, cascadesetting_dcacascdau); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(11, cascadesetting_dcav0dau); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(12, cascadesetting_dcabachtopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(13, cascadesetting_dcapostopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(14, cascadesetting_dcanegtopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(15, cascadesetting_mindcav0topv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(16, cascadesetting_cascradius); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(17, cascadesetting_v0masswindow); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(18, cascadesetting_v0radius); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(19, cascadesetting_rapidity); + } + + // Event selection + Filter eventFilter = (sel8 && o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + // Filters on V0s + Filter preFilterV0 = (nabs(aod::v0data::dcapostopv) > v0setting_dcapostopv && + nabs(aod::v0data::dcanegtopv) > v0setting_dcanegtopv && + aod::v0data::dcaV0daughters < v0setting_dcav0dau && + aod::v0data::v0cosPA > v0setting_cospa); + + // Filters on Cascades + Filter preFilterCascades = (nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv && + aod::cascdata::dcaV0daughters < cascadesetting_dcav0dau && + nabs(aod::cascdata::dcapostopv) > cascadesetting_dcapostopv && + nabs(aod::cascdata::dcanegtopv) > cascadesetting_dcanegtopv && + aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau); + + // Defining the type of the daughter tracks + using DaughterTracks = soa::Join; + + void processData(soa::Filtered>::iterator const& collision, + soa::Filtered const& Cascades, + soa::Filtered const& V0s, + aod::V0Datas const&, // it's needed to access the full table of V0s (not the filtered one) to make sure all the V0s related to cascades are present + aod::V0sLinked const&, + DaughterTracks const&) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + // v0-s loop + for (const auto& v0 : V0s) { + // Decay radius check + if (v0.v0radius() < v0setting_radius) { + continue; + } + // Rapidity check + if (TMath::Abs(v0.yK0Short()) > v0setting_rapidity && + TMath::Abs(v0.yLambda()) > v0setting_rapidity) { + continue; + } + + const auto& posDau = v0.posTrack_as(); + const auto& negDau = v0.negTrack_as(); + + int posITSNhits = 0, negITSNhits = 0; + for (unsigned int i = 0; i < 7; i++) { + if (posDau.itsClusterMap() & (1 << i)) { + posITSNhits++; + } + if (negDau.itsClusterMap() & (1 << i)) { + negITSNhits++; + } + } + + float decayLength = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * RecoDecay::sqrtSumOfSquares(v0.px(), v0.py(), v0.pz()); + float cTauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * pdgDB->Mass(3122); + float cTauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * pdgDB->Mass(310); + + vZerosQC(v0.yK0Short(), v0.yLambda(), + v0.dcaV0daughters(), v0.dcav0topv(), + v0.dcapostopv(), v0.dcanegtopv(), + v0.v0radius(), v0.v0cosPA(), + posDau.tpcNSigmaPi(), posDau.tpcNSigmaPr(), + negDau.tpcNSigmaPi(), negDau.tpcNSigmaPr(), + decayLength, cTauLambda, cTauK0s, + posITSNhits, negITSNhits, + v0.pt(), v0.eta(), + v0.mK0Short(), v0.mLambda(), v0.mAntiLambda(), + posDau.eta(), negDau.eta(), + posDau.phi(), negDau.phi()); + } + + // cascades loop + for (const auto& casc : Cascades) { + const auto& v0index = casc.v0_as(); + if (!(v0index.has_v0Data())) + continue; // skip those cascades for which V0 doesn't exist + + // Rapidity check + if (TMath::Abs(casc.yXi()) > cascadesetting_rapidity && + TMath::Abs(casc.yOmega()) > cascadesetting_rapidity) { + continue; + } + + float casc_v0cospa = casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + float casc_cospa = casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()); + float casc_dcav0topv = casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()); + + // Cut on dynamic columns + if (casc.v0radius() < cascadesetting_v0radius || + casc.cascradius() < cascadesetting_cascradius || + casc_v0cospa < cascadesetting_v0cospa || + casc_cospa < cascadesetting_cospa || + TMath::Abs(casc_dcav0topv) < cascadesetting_mindcav0topv) { + continue; + } + + // Cut on v0 invariant mass + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascadesetting_v0masswindow) + continue; + + const auto& v0Casc = v0index.v0Data(); // de-reference index to correct v0data in case it exists + const auto& bachDau = casc.bachelor_as(); + const auto& posDau = v0Casc.posTrack_as(); + const auto& negDau = v0Casc.negTrack_as(); + + float cascDecayLength = std::hypot(casc.x() - collision.posX(), casc.y() - collision.posY(), casc.z() - collision.posZ()); + float cascTotalMomentum = std::hypot(casc.px(), casc.py(), casc.pz()); + float CtauXi = cascDecayLength / (cascTotalMomentum + 1e-13) * pdgDB->Mass(3312); + float CtauOmega = cascDecayLength / (cascTotalMomentum + 1e-13) * pdgDB->Mass(3334); + + float v0DecayLength = std::hypot(casc.xlambda() - casc.x(), casc.ylambda() - casc.y(), casc.zlambda() - casc.z()); + float v0TotalMomentum = std::hypot(casc.pxpos() + casc.pxneg(), casc.pypos() + casc.pyneg(), casc.pzpos() + casc.pzneg()); + float CtauV0 = v0DecayLength / (v0TotalMomentum + 1e-13) * pdgDB->Mass(3122); + + cascadesQC(casc.sign(), casc.yXi(), casc.yOmega(), + casc_cospa, casc_v0cospa, + casc.cascradius(), casc.v0radius(), + cascDecayLength, CtauXi, CtauOmega, CtauV0, + casc.dcaV0daughters(), casc.dcacascdaughters(), casc_dcav0topv, + casc.dcabachtopv(), casc.dcapostopv(), casc.dcanegtopv(), + posDau.tpcNSigmaPi(), posDau.tpcNSigmaPr(), + negDau.tpcNSigmaPi(), negDau.tpcNSigmaPr(), + bachDau.tpcNSigmaPi(), bachDau.tpcNSigmaKa(), + casc.pt(), casc.eta(), + casc.mLambda(), casc.mOmega(), casc.mXi()); + } + } + PROCESS_SWITCH(strangenessQC, processData, "Process Run 3 data", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"lf-strangenessqc"})}; +} diff --git a/PWGLF/TableProducer/cascadebuilder.cxx b/PWGLF/TableProducer/cascadebuilder.cxx index 4534975f6a1..29c49498842 100644 --- a/PWGLF/TableProducer/cascadebuilder.cxx +++ b/PWGLF/TableProducer/cascadebuilder.cxx @@ -2018,5 +2018,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/TableProducer/cascademcbuilder.cxx b/PWGLF/TableProducer/cascademcbuilder.cxx index 9eb313cb25c..c8be4b0f994 100644 --- a/PWGLF/TableProducer/cascademcbuilder.cxx +++ b/PWGLF/TableProducer/cascademcbuilder.cxx @@ -165,7 +165,7 @@ struct cascademcbuilder { { for (auto& casc : casctable) { // Loop over those that actually have the corresponding V0 associated to them - auto v0 = casc.v0(); + auto v0 = casc.v0_as(); int lLabel = -1; // Acquire all three daughter tracks, please diff --git a/PWGLF/TableProducer/nucleiSpectra.cxx b/PWGLF/TableProducer/nucleiSpectra.cxx index 76631200928..90f5758daed 100644 --- a/PWGLF/TableProducer/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/nucleiSpectra.cxx @@ -288,12 +288,12 @@ struct nucleiSpectra { for (int iPID{0}; iPID < 2; ++iPID) { nuclei::hDCAxy[iPID][iS][iC] = spectra.add(fmt::format("hDCAxy{}_{}_{}", nuclei::pidName[iPID], nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("DCAxy {} {} {}", nuclei::pidName[iPID], nuclei::matter[iC], nuclei::names[iS]).data(), HistType::kTH3D, {centAxis, ptAxes[iS], dcaxyAxes[iS]}); nuclei::hDCAz[iPID][iS][iC] = spectra.add(fmt::format("hDCAz{}_{}_{}", nuclei::pidName[iPID], nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("DCAz {} {} {}", nuclei::pidName[iPID], nuclei::matter[iC], nuclei::names[iS]).data(), HistType::kTH3D, {centAxis, ptAxes[iS], dcazAxes[iS]}); - nuclei::hDeltaP[iPID][iS] = spectra.add(fmt::format("hDeltaP{}_{}", nuclei::pidName[iPID], nuclei::names[iS]).data(), fmt::format("#Delta#it{{p}}/#it{{p}} {} {}", nuclei::pidName[iPID], nuclei::names[iS]).data(), HistType::kTH2D, {{232, 0.2, 6., "#it{{p}} (GeV/#it{{c}})"}, {200, -1, 1, "(#it{{p}}_{{IU}} - #it{{p}}_{{TPC}}) / #it{{p}}"}}); } nuclei::hTOFmass[iS][iC] = spectra.add(fmt::format("h{}TOFmass{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("TOF mass - {} PDG mass", nuclei::names[iS]).data(), HistType::kTH3D, {centAxis, ptAxes[iS], tofMassAxis}); nuclei::hTOFmassEta[iS][iC] = spectra.add(fmt::format("h{}TOFmassEta{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("TOF mass - {} PDG mass", nuclei::names[iS]).data(), HistType::kTH3D, {etaAxis, ptAxes[iS], tofMassAxis}); nuclei::hMomRes[iS][iC] = spectra.add(fmt::format("h{}MomRes{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("Momentum resolution {}", nuclei::names[iS]).data(), HistType::kTH3D, {centAxis, ptAxes[iS], ptResAxis}); nuclei::hGenNuclei[iS][iC] = spectra.add(fmt::format("h{}Gen{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("Generated {}", nuclei::names[iS]).data(), HistType::kTH2D, {centAxis, ptAxes[iS]}); + nuclei::hDeltaP[iC][iS] = spectra.add(fmt::format("hDeltaP{}_{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("#Delta#it{{p}}/#it{{p}} {} {}", nuclei::matter[iC], nuclei::names[iS]).data(), HistType::kTH2D, {{232, 0.2, 6., "#it{{p}} (GeV/#it{{c}})"}, {200, -1.0, 1.0, "(#it{{p}}_{{IU}} - #it{{p}}_{{TPC}}) / #it{{p}}"}}); } } diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/LFNucleiBATask.cxx index 8d81ef2794f..5361d582e4d 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/LFNucleiBATask.cxx @@ -367,10 +367,20 @@ struct LFNucleiBATask { if (enablePr) { histos.add("tracks/proton/h1ProtonSpectra", "#it{p}_{T} (p)", HistType::kTH1F, {ptAxis}); histos.add("tracks/proton/h1antiProtonSpectra", "#it{p}_{T} (#bar{p})", HistType::kTH1F, {ptAxis}); + + histos.add("tracks/proton/h2ProtonYvsPt", "#it{y} vs #it{p}_{T} (p)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/proton/h2antiProtonYvsPt", "#it{y} vs #it{p}_{T} (#bar{p})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/proton/h2ProtonEtavsPt", "#it{#eta} vs #it{p}_{T} (p)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/proton/h2antiProtonEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{p})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableDe) { histos.add("tracks/deuteron/h1DeuteronSpectra", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectra", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); + + histos.add("tracks/deuteron/h2DeuteronYvsPt", "#it{y} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2antiDeuteronYvsPt", "#it{y} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2DeuteronEtavsPt", "it{#eta} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2antiDeuteronEtavsPt", "it{#eta} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableTr) { histos.add("tracks/triton/h1TritonSpectra", "#it{p}_{T} (t)", HistType::kTH1F, {ptAxis}); @@ -380,8 +390,18 @@ struct LFNucleiBATask { histos.add("tracks/helium/h1HeliumSpectra", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectra", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); + histos.add("tracks/helium/h2HeliumYvsPt", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt", "it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h1HeliumSpectra_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectra_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); + + histos.add("tracks/helium/h2antiHeliumYvsPt", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt", "it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectra", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -450,6 +470,14 @@ struct LFNucleiBATask { histos.add("tracks/helium/h1antiHeliumSpectraTruePrim_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectraTrueSec_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectraTrueTransport_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); + if (enablePtSpectra) { + histos.add("tracks/eff/helium/hPtHeTrue", "Track #it{p}_{T} (He); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + histos.add("tracks/eff/helium/hPtantiHeTrue", "Track #it{p}_{T} (#bar{He}); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + if (doTOFplots) { + histos.add("tracks/eff/helium/hPtHeTOFTrue", "Track #it{p}_{T} (He); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + histos.add("tracks/eff/helium/hPtantiHeTOFTrue", "Track #it{p}_{T} (#bar{He}); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + } + } } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectraTrue", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -2361,6 +2389,9 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/proton/h2pVsTPCmomentumPr"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/proton/h1ProtonSpectra"), track.pt()); + histos.fill(HIST("tracks/proton/h2ProtonYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton)), track.pt()); + histos.fill(HIST("tracks/proton/h2ProtonEtavsPt"), track.eta(), track.pt()); + if (enablePIDplot) histos.fill(HIST("tracks/proton/h2TPCsignVsTPCmomentumProton"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaDe()) > 2)) { @@ -2373,6 +2404,9 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/proton/h2pVsTPCmomentumantiPr"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/proton/h1antiProtonSpectra"), track.pt()); + histos.fill(HIST("tracks/proton/h2antiProtonYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton)), track.pt()); + histos.fill(HIST("tracks/proton/h2antiProtonEtavsPt"), track.eta(), track.pt()); + if (enablePIDplot) histos.fill(HIST("tracks/proton/h2TPCsignVsTPCmomentumantiProton"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaDe()) > 2)) { @@ -2383,7 +2417,6 @@ struct LFNucleiBATask { } if (enableDe) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron))) < yCut)) { if ((std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) && deRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { @@ -2391,6 +2424,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/deuteron/h2pVsTPCmomentumDe"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/deuteron/h1DeuteronSpectra"), track.pt()); + histos.fill(HIST("tracks/deuteron/h2DeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), track.pt()); if (enablePIDplot) histos.fill(HIST("tracks/deuteron/h2TPCsignVsTPCmomentumDeuteron"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 1) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCStrongCut)) { @@ -2402,6 +2436,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/deuteron/h2pVsTPCmomentumantiDe"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectra"), track.pt()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), track.pt()); if (enablePIDplot) histos.fill(HIST("tracks/deuteron/h2TPCsignVsTPCmomentumantiDeuteron"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 1) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCStrongCut)) { @@ -2412,7 +2447,6 @@ struct LFNucleiBATask { } if (enableTr) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaTr()) < nsigmaTPCTr)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if ((isTriton) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if (track.sign() > 0) { if (enablePtSpectra) { @@ -2440,7 +2474,6 @@ struct LFNucleiBATask { } } if (enableHe) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3))) < yCut)) { if ((std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) && heRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { @@ -2449,6 +2482,11 @@ struct LFNucleiBATask { } histos.fill(HIST("tracks/helium/h1HeliumSpectra"), hePt); histos.fill(HIST("tracks/helium/h1HeliumSpectra_Z2"), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumEtavsPt"), track.eta(), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumEtavsPt_Z2"), track.eta(), 2 * hePt); + if (enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumHelium"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCStrongCut)) { @@ -2461,6 +2499,10 @@ struct LFNucleiBATask { } histos.fill(HIST("tracks/helium/h1antiHeliumSpectra"), antihePt); histos.fill(HIST("tracks/helium/h1antiHeliumSpectra_Z2"), 2 * antihePt); + histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt"), track.eta(), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumantiHelium"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCStrongCut)) { @@ -2470,7 +2512,6 @@ struct LFNucleiBATask { } } if (enableAl) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaAl()) < nsigmaTPCAl)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { if ((std::abs(track.tpcNSigmaAl()) < nsigmaTPCAl) && TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/h1AlphaSpectra"), track.pt()); @@ -2716,7 +2757,6 @@ struct LFNucleiBATask { } } if (enableDe) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron))) < yCut)) { if ((std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) && deRapCut) { if (track.sign() > 0) { if (enablePtSpectra) @@ -2788,7 +2828,6 @@ struct LFNucleiBATask { } if (enableTr) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaTr()) < nsigmaTPCTr)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if ((isTriton) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if (track.sign() > 0) { if (enablePtSpectra) @@ -3028,6 +3067,12 @@ struct LFNucleiBATask { if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID"), hePt); histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID_Z2"), 2 * hePt); + if (enablePtSpectra) { + histos.fill(HIST("tracks/eff/helium/hPtHeTrue"), 2 * hePt); + if (track.hasTOF() & doTOFplots) { + histos.fill(HIST("tracks/eff/helium/hPtHeTOFTrue"), 2 * hePt); + } + } } if (isPhysPrim) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTruePrim"), hePt); @@ -3062,6 +3107,12 @@ struct LFNucleiBATask { if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID"), antihePt); histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2"), 2 * antihePt); + if (enablePtSpectra) { + histos.fill(HIST("tracks/eff/helium/hPtantiHeTrue"), 2 * hePt); + if (track.hasTOF() & doTOFplots) { + histos.fill(HIST("tracks/eff/helium/hPtantiHeTOFTrue"), 2 * hePt); + } + } } if (isPhysPrim) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTruePrim"), antihePt); diff --git a/PWGLF/Tasks/QC/CMakeLists.txt b/PWGLF/Tasks/QC/CMakeLists.txt index 49d97a2b20d..dd6df615f88 100644 --- a/PWGLF/Tasks/QC/CMakeLists.txt +++ b/PWGLF/Tasks/QC/CMakeLists.txt @@ -63,3 +63,8 @@ o2physics_add_dpl_workflow(efficiencyqa SOURCES efficiencyQA.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(strangenessqcpp + SOURCES strangenessQCPP.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/QC/strangenessQCPP.cxx b/PWGLF/Tasks/QC/strangenessQCPP.cxx new file mode 100644 index 00000000000..6dab146b363 --- /dev/null +++ b/PWGLF/Tasks/QC/strangenessQCPP.cxx @@ -0,0 +1,457 @@ +// 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 strangeness in pb-pb QC task +/// +/// In case of questions please write to: +/// \author Roman Nepeivoda (roman.nepeivoda@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/PIDResponse.h" +#include "PWGLF/DataModel/QC/strangenessTablesQC.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct strangenessQCPP { + // Histogram registries + HistogramRegistry rGeneral{"generalInfo", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + HistogramRegistry rVzero{"vzero", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rCascade{"cascade", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rK0S{"k0S", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rLambda{"lambda", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rAntiLambda{"antiLambda", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rOmega{"omega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rAntiOmega{"antiomega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rXi{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rAntiXi{"antixi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable parameters for V0 selection + Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"}; + Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1, "DCA Pos To PV"}; + Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1, "DCA Neg To PV"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.97, "V0 CosPA"}; // should be double! + Configurable v0setting_radius{"v0setting_radius", 1, "v0radius"}; + Configurable v0setting_rapidity{"v0setting_rapidity", 0.5, "rapidity"}; + + static constexpr float defaultLifetimeCuts[1][2] = {{25., 20.}}; + Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; + + // V0 PID configurables + Configurable NSigmaV0Pion{"NSigmaV0Pion", 6, "NSigmaV0Pion"}; + Configurable NSigmaV0Proton{"NSigmaV0Proton", 6, "NSigmaV0Proton"}; + + // Configurable parameters for cascade selection + Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.98, "Casc CosPA"}; // should be double! + Configurable cascadesetting_v0cospa{"cascadesetting_v0cospa", 0.98, "Casc V0 CosPA"}; // should be double! + Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable cascadesetting_dcav0dau{"cascadesetting_dcav0dau", 1.0, "DCA Cascade's V0 Daughters"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.1, "DCA bachelor to PV"}; + Configurable cascadesetting_dcapostopv{"cascadesetting_dcapostopv", 0.2, "DCA Casc. V0's pos to PV"}; + Configurable cascadesetting_dcanegtopv{"cascadesetting_dcanegtopv", 0.2, "DCA Casc V0's neg to PV"}; + Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "minimum V0 DCA to PV"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 1.0, "cascradius"}; + Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "v0 mass window"}; + Configurable cascadesetting_v0radius{"cascadesetting_v0radius", 0.9, "v0 radius"}; + Configurable cascadesetting_rapidity{"cascadesetting_rapidity", 0.5, "rapidity"}; + + // Cascade PID configurables + Configurable NSigmaCascPion{"NSigmaCascPion", 6, "NSigmaCascPion"}; + Configurable NSigmaCascProton{"NSigmaCascProton", 6, "NSigmaCascProton"}; + Configurable NSigmaCascKaon{"NSigmaCascKaon", 6, "NSigmaCascKaon"}; + + // General axes configurables + ConfigurableAxis binPt{"binPt", {100, 0.0f, 10.0f}, ""}; + ConfigurableAxis binPtsmall{"binPtsmall", {50, 0.0f, 10.0f}, ""}; + ConfigurableAxis binCosPA{"binCosPA", {200, 0.8f, 1.0f}, ""}; + ConfigurableAxis binEtaSmall{"binEtaSmall", {2, -1.0f, 1.0f}, ""}; + ConfigurableAxis binEta{"binEta", {100, -1.0f, 1.0f}, ""}; + ConfigurableAxis binPhi{"binPhi", {(int)TMath::Pi() * 10 / 2, 0.0f, 2. * TMath::Pi()}, ""}; + ConfigurableAxis binRadius{"binRadius", {100, 0.0f, 50.0f}, ""}; + ConfigurableAxis binRadiussmall{"binRadiussmall", {30, 0.0f, 30.0f}, ""}; + ConfigurableAxis binITSMapDaughters{"binITSMapDaughters", {8, -0.5f, 7.5f}, ""}; + + // V0 axes configurables + ConfigurableAxis binV0PA{"binV0PA", {1000, 0.f, 1.0f}, ""}; + ConfigurableAxis binV0Radius{"binV0Radius", {100, 0.0f, 10.0f}, ""}; + ConfigurableAxis binV0DecayLength{"binV0DecayLength", {100, 0.0f, 10.0f}, ""}; + ConfigurableAxis binV0DCANegToPV{"binV0DCANegToPV", {100, -1.0f, 1.0f}, ""}; + ConfigurableAxis binV0DCAPosToPV{"binV0DCAPosToPV", {100, -1.0f, 1.0f}, ""}; + ConfigurableAxis binV0DCAV0Dau{"binV0DCAV0Dau", {55, 0.0f, 2.20f}, ""}; + ConfigurableAxis binCtauK0s{"binCtauK0s", {65, 0.0f, 13.0f}, ""}; + ConfigurableAxis binCtauLambda{"binCtauLambda", {100, 0.0f, 40.0f}, ""}; + ConfigurableAxis binCtauAntiLambda{"binCtauAntiLambda", {100, 0.0f, 40.0f}, ""}; + ConfigurableAxis binDecayLengthK0s{"binDecayLengthK0s", {100, 0.0f, 40.0f}, ""}; + ConfigurableAxis binDecayLengthLambda{"binDecayLengthLambda", {100, 0.0f, 80.0f}, ""}; + ConfigurableAxis binDecayLengthAntiLambda{"binDecayLengthAntiLambda", {100, 0.0f, 80.0f}, ""}; + ConfigurableAxis binV0DCAV0ToPVK0S{"binV0DCAV0ToPVK0S", {250, 0.0f, 0.25f}, ""}; + ConfigurableAxis binV0DCAV0ToPVLambda{"binV0DCAV0ToPVLambda", {250, 0.0f, 0.25f}, ""}; + ConfigurableAxis binV0DCAV0ToPVAntiLambda{"binV0DCAV0ToPVAntiLambda", {250, 0.0f, 0.25f}, ""}; + ConfigurableAxis binInvMassK0S{"binInvMassK0S", {200, 0.4f, 0.6f}, ""}; + ConfigurableAxis binInvMassLambda{"binInvMassLambda", {200, 1.07f, 1.17f}, ""}; + ConfigurableAxis binInvMassAntiLambda{"binInvMassAntiLambda", {200, 1.07f, 1.17f}, ""}; + ConfigurableAxis binResponsePionFromLambda{"binResponsePionFromLambda", {200, -20.f, 20.f}, ""}; + ConfigurableAxis binResponseProtonFromLambda{"binResponseProtonFromLambda", {200, -20.f, 20.f}, ""}; + + // Cascade axes configurables + ConfigurableAxis binCascSign{"binCascSign", {2, -1.5f, 1.5f}, ""}; + ConfigurableAxis binInvMassCasc{"binInvMassCasc", {1000, 0.f, 1.0f}, ""}; + ConfigurableAxis binCascDecayLength{"binCascDecayLength", {100, 0.0f, 10.0f}, ""}; + ConfigurableAxis binCascRadius{"binCascRadius", {100, 0.0f, 10.0f}, ""}; + ConfigurableAxis binCascRapidity{"binCascRapidity", {200, -2.0f, 2.0f}, ""}; + ConfigurableAxis binCascCtau{"binCascCtau", {100, 0.0f, 100.0f}, ""}; + ConfigurableAxis binDcaCascDaughters{"binDcaCascDaughters", {110, 0.0f, 2.2f}, ""}; + ConfigurableAxis binDcaV0ToPV{"binDcaV0ToPV", {200, 0.0f, 2.f}, ""}; + ConfigurableAxis binDcaBachToPV{"binDcaBachToPV", {80, -0.2f, 0.2f}, ""}; + ConfigurableAxis binInvMassXi{"binInvMassXi", {80, 1.28f, 1.36f}, ""}; + ConfigurableAxis binInvMassOmega{"binInvMassOmega", {80, 1.63f, 1.71f}, ""}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // General axes + const AxisSpec axisPt{binPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisPtsmall{binPtsmall, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisCosPA{binCosPA, "Cos(PA)"}; + const AxisSpec axisEta{binEta, "Eta"}; + const AxisSpec axisPhi{binPhi, "Phi"}; + const AxisSpec axisEtaSmall{binEtaSmall, "Eta"}; + const AxisSpec axisRadius{binRadius, "Radius"}; + const AxisSpec axisRadiussmall{binRadiussmall, "Radius"}; + const AxisSpec axisITSMapDaughters{binITSMapDaughters, "ITS Map Daughters"}; + + // V0 axes + const AxisSpec axisV0PA{binV0PA, "Pointing Angle"}; + const AxisSpec axisV0Radius{binV0Radius, "V0 Radius (cm)"}; + const AxisSpec axisV0DecayLength{binV0DecayLength, "V0 Decay Length (cm)"}; + const AxisSpec axisV0DCANegToPV{binV0DCANegToPV, "V0 DCA Neg To PV (cm)"}; + const AxisSpec axisV0DCAPosToPV{binV0DCAPosToPV, "V0 DCA Pos To PV (cm)"}; + const AxisSpec axisV0DCAV0Dau{binV0DCAV0Dau, "V0 DCA V0 Daughters (cm)"}; + const AxisSpec axisCtauK0s{binCtauK0s, "K0s c#tau (cm)"}; + const AxisSpec axisCtauLambda{binCtauLambda, "Lambda c#tau (cm)"}; + const AxisSpec axisCtauAntiLambda{binCtauAntiLambda, "AntiLambda c#tau (cm)"}; + const AxisSpec axisDecayLengthK0s{binDecayLengthK0s, "Decay length K0s (cm)"}; + const AxisSpec axisDecayLengthLambda{binDecayLengthLambda, "Decay length Lambda (cm)"}; + const AxisSpec axisDecayLengthAntiLambda{binDecayLengthAntiLambda, "Decay length AntiLambda (cm)"}; + const AxisSpec axisV0DCAV0ToPVK0S{binV0DCAV0ToPVK0S, "DCAV0ToPV K0s"}; + const AxisSpec axisV0DCAV0ToPVLambda{binV0DCAV0ToPVLambda, "DCAV0ToPV Lambda"}; + const AxisSpec axisV0DCAV0ToPVAntiLambda{binV0DCAV0ToPVAntiLambda, "DCAV0ToPV AntiLambda"}; + const AxisSpec axisInvMassK0S{binInvMassK0S, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + const AxisSpec axisInvMassLambda{binInvMassLambda, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + const AxisSpec axisInvMassAntiLambda{binInvMassAntiLambda, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + const AxisSpec axisInvMassCasc{binInvMassCasc, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + const AxisSpec axisResponsePionFromLambda{binResponsePionFromLambda, "Response Pion From Lambda"}; + const AxisSpec axisResponseProtonFromLambda{binResponseProtonFromLambda, "Response Proton From Lambda"}; + + // Cascade axes + const AxisSpec axisSign{binCascSign, "Casc sign"}; + const AxisSpec axisCascDecayLength{binCascDecayLength, "Casc Decay Length (cm)"}; + const AxisSpec axisCascRadius{binCascRadius, "Casc Radius (cm)"}; + const AxisSpec axisCascRapidity{binCascRapidity, "y"}; + const AxisSpec axisCascCTau{binCascCtau, "y"}; + const AxisSpec axisDcaCascDaughters{binDcaCascDaughters, "DCA Cascade Daughters (cm)"}; + const AxisSpec axisDcaV0ToPV{binDcaV0ToPV, "DCA V0 to PV (cm)"}; + const AxisSpec axisDcaBachToPV{binDcaBachToPV, "DCA Bach to PV (cm)"}; + const AxisSpec axisInvMassXi{binInvMassXi, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + const AxisSpec axisInvMassOmega{binInvMassOmega, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + + // Histograms + // Candidate counter + rGeneral.add("nCandidates", "nCandidates", {HistType::kTH1F, {{2, -0.5f, 1.5f}}}); + + // V0 general histograms + rVzero.add("CosPA", "CosPA", kTH1F, {axisCosPA}); + rVzero.add("V0Radius", "V0Radius", kTH1D, {axisV0Radius}); + rVzero.add("DecayLength", "DecayLength", kTH1F, {axisV0DecayLength}); + rVzero.add("V0DCANegToPV", "V0DCANegToPV", kTH1F, {axisV0DCANegToPV}); + rVzero.add("V0DCAPosToPV", "V0DCAPosToPV", kTH1F, {axisV0DCAPosToPV}); + rVzero.add("V0DCAV0Daughters", "V0DCAV0Daughters", kTH1F, {axisV0DCAV0Dau}); + + // K0s histograms + rK0S.add("CtauK0s", "CtauK0s", kTH1F, {axisCtauK0s}); + rK0S.add("DecayLengthK0s", "DecayLengthK0s", kTH1F, {axisDecayLengthK0s}); + rK0S.add("V0DCAV0ToPVK0S", "V0DCAV0ToPVK0S", kTH1F, {axisV0DCAV0ToPVK0S}); + rK0S.add("InvMassK0S", "InvMassK0S", kTH3F, {axisPt, axisInvMassK0S, axisEtaSmall}); + rK0S.add("InvMassK0SVsPtVsPA", "InvMassK0SVsPtVsPA", kTH3F, {axisPt, axisV0PA, axisInvMassK0S}); + rK0S.add("InvMassK0S_Radius", "InvMassK0S_Radius", kTH2F, {axisRadius, axisInvMassK0S}); + rK0S.add("InvMassK0S_EtaDaughters", "InvMassK0S_EtaDaughters", kTH3F, {axisEta, axisEta, axisInvMassK0S}); + rK0S.add("InvMassK0S_PhiDaughters", "InvMassK0S_PhiDaughters", kTH3F, {axisPhi, axisPhi, axisInvMassK0S}); + rK0S.add("InvMassK0S_ITSMapDaughters", "InvMassK0S_ITSMapDaughters", kTH3F, {axisITSMapDaughters, axisITSMapDaughters, axisInvMassK0S}); + rK0S.add("InvMassK0S_PtRadius", "InvMassK0S_PtRadius", kTH3F, {axisPtsmall, axisRadiussmall, axisInvMassK0S}); + + // Lambda histograms + rLambda.add("CtauLambda", "CtauLambda", kTH1F, {axisCtauLambda}); + rLambda.add("DecayLengthLambda", "DecayLengthLambda", kTH1F, {axisDecayLengthLambda}); + rLambda.add("V0DCAV0ToPVLambda", "V0DCAV0ToPVLambda", kTH1F, {axisV0DCAV0ToPVLambda}); + rLambda.add("InvMassLambda", "InvMassLambda", kTH3F, {axisPt, axisInvMassLambda, axisEtaSmall}); + rLambda.add("InvMassLambdaVsPtVsPA", "InvMassLambdaVsPtVsPA", kTH3F, {axisPt, axisV0PA, axisInvMassLambda}); + rLambda.add("InvMassLambda_Radius", "InvMassLambda_Radius", kTH2F, {axisRadius, axisInvMassLambda}); + rLambda.add("InvMassLambda_EtaDaughters", "InvMassLambda_EtaDaughters", kTH3F, {axisEta, axisEta, axisInvMassLambda}); + rLambda.add("InvMassLambda_Ctau", "InvMassLambda_Ctau", kTH2F, {axisCtauLambda, axisInvMassLambda}); + rLambda.add("InvMassLambda_PhiDaughters", "InvMassLambda_PhiDaughters", kTH3F, {axisPhi, axisPhi, axisInvMassLambda}); + rLambda.add("InvMassLambda_ITSMapDaughters", "InvMassLambda_ITSMapDaughters", kTH3F, {axisITSMapDaughters, axisITSMapDaughters, axisInvMassLambda}); + rLambda.add("InvMassLambda_PtRadius", "InvMassLambda_PtRadius", kTH3F, {axisPtsmall, axisRadiussmall, axisInvMassLambda}); + rLambda.add("ResponsePionFromLambda", "ResponsePionFromLambda", kTH2F, {axisPt, axisResponsePionFromLambda}); + rLambda.add("ResponseProtonFromLambda", "ResponseProtonFromLambda", kTH2F, {axisPt, axisResponseProtonFromLambda}); + + // Anti-Lambda histograms + rAntiLambda.add("CtauAntiLambda", "CtauAntiLambda", kTH1F, {axisCtauAntiLambda}); + rAntiLambda.add("DecayLengthAntiLambda", "DecayLengthAntiLambda", kTH1F, {axisDecayLengthAntiLambda}); + rAntiLambda.add("V0DCAV0ToPVAntiLambda", "V0DCAV0ToPVAntiLambda", kTH1F, {axisV0DCAV0ToPVAntiLambda}); + rAntiLambda.add("InvMassAntiLambda", "InvMassAntiLambda", kTH3F, {axisPt, axisInvMassAntiLambda, axisEtaSmall}); + rAntiLambda.add("InvMassAntiLambdaVsPtVsPA", "InvMassAntiLambdaVsPtVsPA", kTH3F, {axisPt, axisV0PA, axisInvMassAntiLambda}); + rAntiLambda.add("InvMassAntiLambda_Radius", "InvMassAntiLambda_Radius", kTH2F, {axisRadius, axisInvMassAntiLambda}); + rAntiLambda.add("InvMassAntiLambda_EtaDaughters", "InvMassAntiLambda_EtaDaughters", kTH3F, {axisEta, axisEta, axisInvMassAntiLambda}); + rAntiLambda.add("InvMassAntiLambda_Ctau", "InvMassAntiLambda_Ctau", kTH2F, {axisCtauAntiLambda, axisInvMassAntiLambda}); + rAntiLambda.add("InvMassAntiLambda_PhiDaughters", "InvMassAntiLambda_PhiDaughters", kTH3F, {axisPhi, axisPhi, axisInvMassAntiLambda}); + rAntiLambda.add("InvMassAntiLambda_ITSMapDaughters", "InvMassAntiLambda_ITSMapDaughters", kTH3F, {axisITSMapDaughters, axisITSMapDaughters, axisInvMassAntiLambda}); + rAntiLambda.add("InvMassAntiLambda_PtRadius", "InvMassAntiLambda_PtRadius", kTH3F, {axisPtsmall, axisRadiussmall, axisInvMassAntiLambda}); + + // Cascade general histograms + rCascade.add("V0Radius", "V0Radius", {HistType::kTH2D, {axisV0Radius, axisSign}}); + rCascade.add("CascCosPA", "CascCosPA", {HistType::kTH2F, {axisCosPA, axisSign}}); + rCascade.add("V0CosPA", "V0CosPA", {HistType::kTH2F, {axisCosPA, axisSign}}); + rCascade.add("CascDecayLength", "CascDecayLength", {HistType::kTH2F, {axisCascDecayLength, axisSign}}); + rCascade.add("CascRadius", "CascRadius", {HistType::kTH2F, {axisCascRadius, axisSign}}); + rCascade.add("CascyXi", "CascyXi", {HistType::kTH2F, {axisCascRapidity, axisSign}}); + rCascade.add("CascyOmega", "CascyOmega", {HistType::kTH2F, {axisCascRapidity, axisSign}}); + rCascade.add("CascCtauXi", "CascCtauXi", {HistType::kTH2F, {axisCascCTau, axisSign}}); + rCascade.add("CascCtauOmega", "CascCtauOmega", {HistType::kTH2F, {axisCascCTau, axisSign}}); + rCascade.add("V0Ctau", "V0Ctau", {HistType::kTH2F, {axisCascCTau, axisSign}}); + rCascade.add("CascPt", "CascPt", {HistType::kTH2F, {binPt, axisSign}}); + rCascade.add("DcaV0Daughters", "DcaV0Daughters", {HistType::kTH2F, {axisV0DCAV0Dau, axisSign}}); + rCascade.add("DcaCascDaughters", "DcaCascDaughters", {HistType::kTH2F, {axisDcaCascDaughters, axisSign}}); + rCascade.add("DcaV0ToPV", "DcaV0ToPV", {HistType::kTH2F, {axisDcaV0ToPV, axisSign}}); + rCascade.add("DcaBachToPV", "DcaBachToPV", {HistType::kTH2F, {axisDcaBachToPV, axisSign}}); + rCascade.add("DcaPosToPV", "DcaPosToPV", {HistType::kTH2F, {axisV0DCAPosToPV, axisSign}}); + rCascade.add("DcaNegToPV", "DcaNegToPV", {HistType::kTH2F, {axisV0DCANegToPV, axisSign}}); + rCascade.add("InvMassLambdaDaughter", "InvMassLambdaDaughter", {HistType::kTH2F, {axisInvMassLambda, axisSign}}); + // rCascade.add("V0CosPAToXi", "V0CosPAToXi", {HistType::kTH2F, {{100, 0.9f, 1.0f}, axisSign}}); + + // Xi histograms + rXi.add("InvMassXiMinus", "InvMassXiMinus", {HistType::kTH3F, {axisPt, axisInvMassXi, axisEta}}); + rXi.add("InvMassXiMinus_Radius", "InvMassXiMinus_Radius", {HistType::kTH2F, {axisPt, axisInvMassXi}}); + + // Anti-Xi histograms + rAntiXi.add("InvMassXiPlus", "InvMassXiPlus", {HistType::kTH3F, {axisPt, axisInvMassXi, axisEta}}); + rAntiXi.add("InvMassXiPlus_Radius", "InvMassXiPlus_Radius", {HistType::kTH2F, {axisPt, axisInvMassXi}}); + + // Omega histograms + rOmega.add("InvMassOmegaMinus", "InvMassOmegaMinus", {HistType::kTH3F, {axisPt, axisInvMassOmega, axisEta}}); + + // Anti-Omega histograms + rAntiOmega.add("InvMassOmegaPlus", "InvMassOmegaPlus", {HistType::kTH3F, {axisPt, axisInvMassOmega, axisEta}}); + + // Cut summary + rGeneral.add("selectionSummary", "selectionSummary", HistType::kTH1F, {{18, -0.5, 17.5}}); + TString CutLabelSummary[18] = {"v0_dcav0dau", "v0_dcapostopv", "v0_dcanegtopv", "v0_cospa", "v0_radius", "v0_rapidity", + "casc_cospa", "casc_v0cospa", "casc_dcacascdau", "casc_dcav0dau", "casc_dcabachtopv", "casc_dcapostopv", "casc_dcanegtopv", "casc_mindcav0topv", "casc_cascradius", "casc_v0masswindow", "casc_v0radius", "casc_rapidity"}; + for (Int_t n = 1; n <= rGeneral.get(HIST("selectionSummary"))->GetNbinsX(); n++) { + rGeneral.get(HIST("selectionSummary"))->GetXaxis()->SetBinLabel(n, CutLabelSummary[n - 1]); + } + rGeneral.get(HIST("selectionSummary"))->SetBinContent(1, v0setting_dcav0dau); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(2, v0setting_dcapostopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(3, v0setting_dcanegtopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(4, v0setting_cospa); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(5, v0setting_radius); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(6, v0setting_rapidity); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(7, cascadesetting_cospa); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(8, cascadesetting_v0cospa); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(9, cascadesetting_dcacascdau); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(10, cascadesetting_dcav0dau); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(11, cascadesetting_dcabachtopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(12, cascadesetting_dcapostopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(13, cascadesetting_dcanegtopv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(14, cascadesetting_mindcav0topv); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(15, cascadesetting_cascradius); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(16, cascadesetting_v0masswindow); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(17, cascadesetting_v0radius); + rGeneral.get(HIST("selectionSummary"))->SetBinContent(18, cascadesetting_rapidity); + } + + template + void fillV0Histograms(TV0 const& v0) + { + rVzero.fill(HIST("CosPA"), v0.v0cosPA()); + rVzero.fill(HIST("V0Radius"), v0.v0radius()); + rVzero.fill(HIST("V0DCANegToPV"), v0.dcanegtopv()); + rVzero.fill(HIST("V0DCAPosToPV"), v0.dcapostopv()); + rVzero.fill(HIST("V0DCAV0Daughters"), v0.dcaV0daughters()); + rVzero.fill(HIST("DecayLength"), v0.decayLength()); + } + + template + void fillCascadeHistograms(TCascade const& casc) + { + rCascade.fill(HIST("V0Radius"), casc.v0radius(), casc.sign()); + rCascade.fill(HIST("CascCosPA"), casc.casccosPA(), casc.sign()); + rCascade.fill(HIST("V0CosPA"), casc.v0cosPA(), casc.sign()); + rCascade.fill(HIST("CascRadius"), casc.cascradius(), casc.sign()); + rCascade.fill(HIST("CascDecayLength"), casc.decayLength(), casc.sign()); + rCascade.fill(HIST("CascPt"), casc.pt(), casc.sign()); + rCascade.fill(HIST("DcaV0Daughters"), casc.dcaV0daughters(), casc.sign()); + rCascade.fill(HIST("DcaCascDaughters"), casc.dcacascdaughters(), casc.sign()); + rCascade.fill(HIST("DcaV0ToPV"), casc.dcav0topv(), casc.sign()); + rCascade.fill(HIST("DcaBachToPV"), casc.dcabachtopv(), casc.sign()); + rCascade.fill(HIST("DcaPosToPV"), casc.dcapostopv(), casc.sign()); + rCascade.fill(HIST("DcaNegToPV"), casc.dcanegtopv(), casc.sign()); + rCascade.fill(HIST("InvMassLambdaDaughter"), casc.mLambda(), casc.sign()); + rCascade.fill(HIST("V0Ctau"), casc.lifetimeV0(), casc.sign()); + } + + // Filters on V0s + Filter preFilterV0 = (nabs(aod::vZerosQC::dcapostopv) > v0setting_dcapostopv && + nabs(aod::vZerosQC::dcanegtopv) > v0setting_dcanegtopv && + aod::vZerosQC::dcaV0daughters < v0setting_dcav0dau && + aod::vZerosQC::v0cosPA > v0setting_cospa && + aod::vZerosQC::v0radius > v0setting_radius); + + // Filters on Cascades + Filter preFilterCascades = (nabs(aod::cascadesQC::dcabachtopv) > cascadesetting_dcabachtopv && + aod::cascadesQC::dcaV0daughters < cascadesetting_dcav0dau && + nabs(aod::cascadesQC::dcapostopv) > cascadesetting_dcapostopv && + nabs(aod::cascadesQC::dcanegtopv) > cascadesetting_dcanegtopv && + aod::cascadesQC::dcacascdaughters < cascadesetting_dcacascdau && + aod::cascadesQC::dcaV0daughters < cascadesetting_dcav0dau && + aod::cascadesQC::v0radius > cascadesetting_v0radius && + aod::cascadesQC::cascradius > cascadesetting_cascradius && + nabs(aod::cascadesQC::dcav0topv) > cascadesetting_mindcav0topv && + aod::cascadesQC::v0cosPA > cascadesetting_v0cospa && + aod::cascadesQC::casccosPA > cascadesetting_cospa); + + void processV0(soa::Filtered const& v0s) + { + for (const auto& v0 : v0s) { + // Fill the candidate counter + rGeneral.fill(HIST("nCandidates"), 0); + + // K0Short + if (TMath::Abs(v0.yK0Short()) < v0setting_rapidity && + v0.lifetimeK0s() < lifetimecut->get("lifetimecutK0S") && + TMath::Abs(v0.posNSigmaV0Pion()) < NSigmaV0Pion && TMath::Abs(v0.negNSigmaV0Pion()) < NSigmaV0Pion) { + fillV0Histograms(v0); + rK0S.fill(HIST("DecayLengthK0s"), v0.decayLength()); + rK0S.fill(HIST("CtauK0s"), v0.lifetimeK0s()); + rK0S.fill(HIST("InvMassK0S"), v0.pt(), v0.mK0Short(), v0.eta()); + rK0S.fill(HIST("InvMassK0SVsPtVsPA"), v0.pt(), TMath::ACos(v0.v0cosPA()), v0.mK0Short()); + rK0S.fill(HIST("V0DCAV0ToPVK0S"), v0.dcav0topv()); + rK0S.fill(HIST("InvMassK0S_Radius"), v0.v0radius(), v0.mK0Short()); + rK0S.fill(HIST("InvMassK0S_PtRadius"), v0.pt(), v0.v0radius(), v0.mK0Short()); + rK0S.fill(HIST("InvMassK0S_EtaDaughters"), v0.poseta(), v0.negeta(), v0.mK0Short()); + rK0S.fill(HIST("InvMassK0S_PhiDaughters"), v0.posphi(), v0.negphi(), v0.mK0Short()); + rK0S.fill(HIST("InvMassK0S_ITSMapDaughters"), v0.posITSNhits(), v0.negITSNhits(), v0.mK0Short()); + } + + // Lambda + if (TMath::Abs(v0.yLambda()) < v0setting_rapidity && + v0.lifetimeLambda() < lifetimecut->get("lifetimecutLambda") && + TMath::Abs(v0.posNSigmaV0Proton()) < NSigmaV0Proton && TMath::Abs(v0.negNSigmaV0Pion()) < NSigmaV0Pion) { + fillV0Histograms(v0); + rLambda.fill(HIST("DecayLengthLambda"), v0.decayLength()); + rLambda.fill(HIST("CtauLambda"), v0.lifetimeLambda()); + rLambda.fill(HIST("InvMassLambda"), v0.pt(), v0.mLambda(), v0.eta()); + rLambda.fill(HIST("InvMassLambdaVsPtVsPA"), v0.pt(), TMath::ACos(v0.v0cosPA()), v0.mLambda()); + rLambda.fill(HIST("V0DCAV0ToPVLambda"), v0.dcav0topv()); + rLambda.fill(HIST("InvMassLambda_Radius"), v0.v0radius(), v0.mLambda()); + rLambda.fill(HIST("InvMassLambda_PtRadius"), v0.pt(), v0.v0radius(), v0.mLambda()); + rLambda.fill(HIST("InvMassLambda_EtaDaughters"), v0.poseta(), v0.negeta(), v0.mLambda()); + rLambda.fill(HIST("InvMassLambda_PhiDaughters"), v0.posphi(), v0.negphi(), v0.mLambda()); + rLambda.fill(HIST("InvMassLambda_Ctau"), v0.lifetimeLambda(), v0.mLambda()); + rLambda.fill(HIST("InvMassLambda_ITSMapDaughters"), v0.posITSNhits(), v0.negITSNhits(), v0.mLambda()); + if (v0.v0cosPA() > 0.999 && v0.dcaV0daughters() < 1 && TMath::Abs(v0.mK0Short() - pdgDB->Mass(310)) > 0.012 && TMath::Abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) > 0.08 && TMath::Abs(v0.mLambda() - o2::constants::physics::MassLambda0) < 0.002) { + rLambda.fill(HIST("ResponsePionFromLambda"), v0.pt(), v0.negNSigmaV0Pion()); + rLambda.fill(HIST("ResponseProtonFromLambda"), v0.pt(), v0.posNSigmaV0Proton()); + } + } + + // AntiLambda + if (TMath::Abs(v0.yLambda()) < v0setting_rapidity && + v0.lifetimeLambda() < lifetimecut->get("lifetimecutLambda") && + TMath::Abs(v0.posNSigmaV0Pion()) < NSigmaV0Pion && TMath::Abs(v0.negNSigmaV0Proton()) < NSigmaV0Proton) { + fillV0Histograms(v0); + rAntiLambda.fill(HIST("DecayLengthAntiLambda"), v0.decayLength()); + rAntiLambda.fill(HIST("CtauAntiLambda"), v0.lifetimeLambda()); + rAntiLambda.fill(HIST("InvMassAntiLambda"), v0.pt(), v0.mAntiLambda(), v0.eta()); + rAntiLambda.fill(HIST("InvMassAntiLambdaVsPtVsPA"), v0.pt(), TMath::ACos(v0.v0cosPA()), v0.mAntiLambda()); + rAntiLambda.fill(HIST("V0DCAV0ToPVAntiLambda"), v0.dcav0topv()); + rAntiLambda.fill(HIST("InvMassAntiLambda_Radius"), v0.v0radius(), v0.mAntiLambda()); + rAntiLambda.fill(HIST("InvMassAntiLambda_PtRadius"), v0.pt(), v0.v0radius(), v0.mAntiLambda()); + rAntiLambda.fill(HIST("InvMassAntiLambda_EtaDaughters"), v0.poseta(), v0.negeta(), v0.mAntiLambda()); + rAntiLambda.fill(HIST("InvMassAntiLambda_PhiDaughters"), v0.posphi(), v0.negphi(), v0.mAntiLambda()); + rAntiLambda.fill(HIST("InvMassAntiLambda_Ctau"), v0.lifetimeLambda(), v0.mAntiLambda()); + rAntiLambda.fill(HIST("InvMassAntiLambda_ITSMapDaughters"), v0.posITSNhits(), v0.negITSNhits(), v0.mAntiLambda()); + } + } + } + PROCESS_SWITCH(strangenessQCPP, processV0, "Process V0 candidates", true); + + void processCascade(soa::Filtered const& cascades) + { + for (const auto& casc : cascades) { + // Fill the candidate counter + rGeneral.fill(HIST("nCandidates"), 1); + + if (casc.sign() < 0) { + // Check lambda daughters` PID + if (TMath::Abs(casc.posNSigmaV0Proton()) < NSigmaCascProton && TMath::Abs(casc.negNSigmaV0Pion()) < NSigmaCascPion) { + // Xi + if (TMath::Abs(casc.yXi()) < cascadesetting_rapidity && TMath::Abs(casc.bachNSigmaV0Pion()) < NSigmaCascPion) { + fillCascadeHistograms(casc); + rXi.fill(HIST("InvMassXiMinus"), casc.pt(), casc.mXi(), casc.eta()); + rXi.fill(HIST("InvMassXiMinus_Radius"), casc.cascradius(), casc.mXi()); + rCascade.fill(HIST("CascyXi"), casc.yXi(), casc.sign()); + rCascade.fill(HIST("CascCtauXi"), casc.lifetimeXi(), casc.sign()); + } + // Omega + if (TMath::Abs(casc.yOmega()) < cascadesetting_rapidity && TMath::Abs(casc.bachNSigmaV0Kaon()) < NSigmaCascKaon) { + fillCascadeHistograms(casc); + rOmega.fill(HIST("InvMassOmegaMinus"), casc.pt(), casc.mOmega(), casc.eta()); + rCascade.fill(HIST("CascCtauOmega"), casc.lifetimeOmega(), casc.sign()); + rCascade.fill(HIST("CascyOmega"), casc.yOmega(), casc.sign()); + } + } + } else { + // Check anti-lambda daughters` PID + if (TMath::Abs(casc.posNSigmaV0Pion()) < NSigmaCascPion && TMath::Abs(casc.negNSigmaV0Proton()) < NSigmaCascProton) { + // Anti-Xi + if (TMath::Abs(casc.yXi()) < cascadesetting_rapidity && TMath::Abs(casc.bachNSigmaV0Pion()) < NSigmaCascPion) { + fillCascadeHistograms(casc); + rAntiXi.fill(HIST("InvMassXiPlus"), casc.pt(), casc.mXi(), casc.eta()); + rAntiXi.fill(HIST("InvMassXiPlus_Radius"), casc.cascradius(), casc.mXi()); + rCascade.fill(HIST("CascyXi"), casc.yXi(), casc.sign()); + rCascade.fill(HIST("CascCtauXi"), casc.lifetimeXi(), casc.sign()); + } + // Anti-Omega + if (TMath::Abs(casc.yOmega()) < cascadesetting_rapidity && TMath::Abs(casc.bachNSigmaV0Kaon()) < NSigmaCascKaon) { + fillCascadeHistograms(casc); + rAntiOmega.fill(HIST("InvMassOmegaPlus"), casc.pt(), casc.mOmega(), casc.eta()); + rCascade.fill(HIST("CascCtauOmega"), casc.lifetimeOmega(), casc.sign()); + rCascade.fill(HIST("CascyOmega"), casc.yOmega(), casc.sign()); + } + } + } + } + } + PROCESS_SWITCH(strangenessQCPP, processCascade, "Process cascade candidates", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"lf-strangenessqcpp"})}; +} \ No newline at end of file diff --git a/PWGLF/Tasks/f1protoncorrelation.cxx b/PWGLF/Tasks/f1protoncorrelation.cxx index 6048b7dccf1..a42c879ca50 100644 --- a/PWGLF/Tasks/f1protoncorrelation.cxx +++ b/PWGLF/Tasks/f1protoncorrelation.cxx @@ -57,8 +57,8 @@ struct f1protoncorrelation { void init(o2::framework::InitContext&) { // register histograms - histos.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 10.0f}}); - histos.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 10.0f}}); + histos.add("hNsigmaProtonTPCSE", "Nsigma Proton TPC distribution same event", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 1.0f}}); + histos.add("hNsigmaProtonTPCME", "Nsigma Proton TPC distribution mixed event", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 1.0f}}); histos.add("h2SameEventPtCorrelation", "Pt correlation of F1 and proton", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {100, 0.0, 10.0}}); histos.add("h2SameEventInvariantMassUnlike_mass104", "Unlike Sign Invariant mass of f1 same event", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {800, 1.0, 1.8}}); histos.add("h2MixEventInvariantMassUnlike_mass104", "Unlike Sign Invariant mass of f1 mix event", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {800, 1.0, 1.8}}); @@ -133,37 +133,38 @@ struct f1protoncorrelation { continue; } auto relative_momentum = getkstar(F1, Proton); - histos.fill(HIST("h2SameEventPtCorrelation"), relative_momentum, Pion.P() / Kaon.P(), Proton.Pt()); + histos.fill(HIST("h2SameEventPtCorrelation"), relative_momentum, F1.Pt(), Proton.Pt()); if (f1track.f1MassKaonKshort() < 1.04) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass104"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("hNsigmaProtonTPCSE"), protontrack.protonNsigmaTPC(), relative_momentum); } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass104"), relative_momentum, F1.Pt(), F1.M()); } } if (f1track.f1MassKaonKshort() < 1.03) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass103"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass103"), relative_momentum, F1.Pt(), F1.M()); } } if (f1track.f1MassKaonKshort() < 1.02) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass102"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass102"), relative_momentum, F1.Pt(), F1.M()); } } if (f1track.f1MassKaonKshort() < 1.01) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass101"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass101"), relative_momentum, F1.Pt(), F1.M()); } } } @@ -224,34 +225,35 @@ struct f1protoncorrelation { auto relative_momentum = getkstar(F1, Proton); if (t1.f1MassKaonKshort() < 1.04) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass104"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("hNsigmaProtonTPCME"), t2.protonNsigmaTPC(), relative_momentum); } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass104"), relative_momentum, F1.Pt(), F1.M()); } } if (t1.f1MassKaonKshort() < 1.03) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass103"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass103"), relative_momentum, F1.Pt(), F1.M()); } } if (t1.f1MassKaonKshort() < 1.02) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass102"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass102"), relative_momentum, F1.Pt(), F1.M()); } } if (t1.f1MassKaonKshort() < 1.01) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass101"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass101"), relative_momentum, F1.Pt(), F1.M()); } } } diff --git a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx index c99a606df83..4535d908a24 100644 --- a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx +++ b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx @@ -88,7 +88,7 @@ struct lambdaAnalysis { // Define Axis. const AxisSpec axisSp(nBinsSp, 0., 1., "S_{0}"); const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); - const AxisSpec axisPtQA(40, 0., 2., "p_{T} (GeV/c)"); + const AxisSpec axisPtQA(100, 0., 2., "p_{T} (GeV/c)"); const AxisSpec axisPt(nBinsPt, 0., 10., "p_{T} (GeV/c)"); const AxisSpec axisEta(40, -1, 1, "#eta"); const AxisSpec axisDCAz(500, -0.5, 0.5, {"DCA_{z} (cm)"}); @@ -96,7 +96,7 @@ struct lambdaAnalysis { const AxisSpec axisTPCNCls(200, 0, 200, {"TPCNCls"}); const AxisSpec axisTPCNsigma(120, -6, 6, {"n#sigma^{TPC}"}); const AxisSpec axisTOFNsigma(120, -6, 6, {"n#sigma^{TOF}"}); - const AxisSpec axisInvM(nBinsInvM, 1.44, 2.04, {"M_{inv} (GeV/c^{2})"}); + const AxisSpec axisInvM(nBinsInvM, 1.44, 2.44, {"M_{inv} (GeV/c^{2})"}); // Create Histograms. // Event @@ -116,17 +116,19 @@ struct lambdaAnalysis { histos.add("QAafter/Proton/hPt", "p_{T}-spectra Protons", kTH1F, {axisPt}); histos.add("QAafter/Proton/hDcaZ", "dca_{z} Protons", kTH2F, {axisPtQA, axisDCAz}); histos.add("QAafter/Proton/hDcaXY", "dca_{xy} Protons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAafter/Proton/hTPCNsigma", "n#sigma^{TPC} only Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma^{TPC} Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTOFNsigma", "n#sigma^{TOF} Protons", kTH2F, {axisPtQA, axisTOFNsigma}); - histos.add("QAafter/Proton/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Proton/hTPCNsigmaFull", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Proton/hTPCNsigma", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Proton/hTOFNsigma", "n#sigma(TOF) Protons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAafter/Proton/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); histos.add("QAafter/Kaon/hPt", "p_{T}-spectra Kaons", kTH1F, {axisPt}); histos.add("QAafter/Kaon/hDcaZ", "dca_{z} Kaons", kTH2F, {axisPtQA, axisDCAz}); histos.add("QAafter/Kaon/hDcaXY", "dca_{xy} Kaons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma^{TPC} only Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma^{TPC} Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma^{TOF} Kaons", kTH2F, {axisPtQA, axisTOFNsigma}); - histos.add("QAafter/Kaon/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Kaon/hTPCNsigmaFull", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma(TOF) Kaons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAafter/Kaon/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // Analysis // Lambda Invariant Mass @@ -135,11 +137,13 @@ struct lambdaAnalysis { histos.add("Analysis/hInvMassLS2", "Like Signs M_{inv} #bar{p} K^{-}", kTH1D, {axisInvM}); histos.add("Analysis/hInvMassR", "Rotated Spectra", kTH1D, {axisInvM}); histos.add("Analysis/hInvMassMix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/hInvMassMixLS", "Mixed Events M_{inv}", kTH1D, {axisInvM}); histos.add("Analysis/h4InvMass", "THn #Lambda(1520)", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassLS1", "THn Like Signs p K^{+}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassLS2", "THn Like Signs #bar{p} K^{-}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassR", "THn Rotated", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassMix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4InvMassMixLS", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); // MC if (doprocessMC) { @@ -321,6 +325,7 @@ struct lambdaAnalysis { histos.fill(HIST("QAafter/Proton/hPt"), trkPr.pt()); histos.fill(HIST("QAafter/Proton/hDcaZ"), trkPr.pt(), trkPr.dcaZ()); histos.fill(HIST("QAafter/Proton/hDcaXY"), trkPr.pt(), trkPr.dcaXY()); + histos.fill(HIST("QAafter/Proton/hTPCNsigmaFull"), trkPr.pt(), trkPr.tpcNSigmaPr()); if (!cUseTpcOnly && trkPr.hasTOF()) { histos.fill(HIST("QAafter/Proton/hTPCNsigmaTOF"), trkPr.pt(), trkPr.tpcNSigmaPr()); histos.fill(HIST("QAafter/Proton/hTOFNsigma"), trkPr.pt(), trkPr.tofNSigmaPr()); @@ -331,6 +336,7 @@ struct lambdaAnalysis { histos.fill(HIST("QAafter/Kaon/hPt"), trkKa.pt()); histos.fill(HIST("QAafter/Kaon/hDcaZ"), trkKa.pt(), trkKa.dcaZ()); histos.fill(HIST("QAafter/Kaon/hDcaXY"), trkKa.pt(), trkKa.dcaXY()); + histos.fill(HIST("QAafter/Kaon/hTPCNsigmaFull"), trkKa.pt(), trkKa.tpcNSigmaKa()); if (!cUseTpcOnly && trkKa.hasTOF()) { histos.fill(HIST("QAafter/Kaon/hTPCNsigmaTOF"), trkKa.pt(), trkKa.tpcNSigmaKa()); histos.fill(HIST("QAafter/Kaon/hTOFNsigma"), trkKa.pt(), trkKa.tofNSigmaKa()); @@ -414,6 +420,9 @@ struct lambdaAnalysis { if (trkPr.sign() * trkKa.sign() < 0) { histos.fill(HIST("Analysis/hInvMassMix"), p.M()); histos.fill(HIST("Analysis/h4InvMassMix"), p.M(), p.Pt(), sph, mult); + } else { + histos.fill(HIST("Analysis/hInvMassMixLS"), p.M()); + histos.fill(HIST("Analysis/h4InvMassMixLS"), p.M(), p.Pt(), sph, mult); } } } diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 820f95c6b5f..c7cfcf02636 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -88,12 +89,16 @@ struct nuclei_in_jets { Configurable max_chi2_TPC{"max_chi2_TPC", 4.0f, "maximum TPC chi^2/Ncls"}; Configurable max_chi2_ITS{"max_chi2_ITS", 36.0f, "maximum ITS chi^2/Ncls"}; Configurable min_pt{"min_pt", 0.2f, "minimum pt of the tracks"}; - Configurable min_eta{"min_eta", -0.8f, "minimum_eta"}; - Configurable max_eta{"max_eta", +0.8f, "maximum_eta"}; + Configurable min_eta{"min_eta", -0.8f, "minimum eta"}; + Configurable max_eta{"max_eta", +0.8f, "maximum eta"}; + Configurable min_y{"min_y", -0.5f, "minimum y"}; + Configurable max_y{"max_y", +0.5f, "maximum y"}; Configurable max_dcaxy{"max_dcaxy", 0.1f, "Maximum DCAxy"}; Configurable max_dcaz{"max_dcaz", 0.1f, "Maximum DCAz"}; Configurable min_nsigmaTPC{"min_nsigmaTPC", -3.0f, "Minimum nsigma TPC"}; Configurable max_nsigmaTPC{"max_nsigmaTPC", +3.0f, "Maximum nsigma TPC"}; + Configurable min_nsigmaTOF{"min_nsigmaTOF", -3.0f, "Minimum nsigma TOF"}; + Configurable max_nsigmaTOF{"max_nsigmaTOF", +3.5f, "Maximum nsigma TOF"}; Configurable require_primVtx_contributor{"require_primVtx_contributor", true, "require that the track is a PV contributor"}; // List of Particles @@ -104,13 +109,15 @@ struct nuclei_in_jets { void init(InitContext const&) { // Global Properties and QC - registryQC.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{5, 0, 5, "1 = all events, 2 = selected events, 3 = events with pt>pt_threshold, 4 = events with pt>pt_threshold and particle of interest"}}); - registryQC.add("jet_plus_ue_multiplicity", "jet + underlying-event multiplicity", HistType::kTH1F, {{300, 0, 300, "#it{N}_{ch}"}}); - registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{300, 0, 300, "#it{N}_{ch}"}}); - registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{300, 0, 300, "#it{N}_{ch}"}}); + registryQC.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{10, 0, 10, "counter"}}); + registryQC.add("number_of_events_mc", "number of events in mc", HistType::kTH1F, {{10, 0, 10, "counter"}}); + registryQC.add("jet_plus_ue_multiplicity", "jet + underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); + registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); + registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("pt_leading", "pt leading", HistType::kTH1F, {{500, 0, 50, "#it{p}_{T} (GeV/#it{c})"}}); registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{500, -0.5, 0.5, "#Delta#eta"}, {500, 0.0, TMath::Pi(), "#Delta#phi"}}); registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{500, -0.5, 0.5, "#Delta#eta"}, {500, 0.0, TMath::Pi(), "#Delta#phi"}}); + registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}_{max}"}}); registryQC.add("r_jet", "R jet", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}"}}); registryQC.add("r_ue", "R ue", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}"}}); @@ -129,6 +136,20 @@ struct nuclei_in_jets { // Antihelium-3 registryData.add("antihelium3_jet_tpc", "antihelium3_jet_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); registryData.add("antihelium3_ue_tpc", "antihelium3_ue_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); + + // Generated + registryMC.add("antiproton_gen", "antiproton_gen", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_gen", "antideuteron_gen", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_gen", "antihelium3_gen", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed TPC + registryMC.add("antiproton_rec_tpc", "antiproton_rec_tpc", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tpc", "antideuteron_rec_tpc", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_rec_tpc", "antihelium3_rec_tpc", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed TOF + registryMC.add("antiproton_rec_tof", "antiproton_rec_tof", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof", "antideuteron_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); } // Single-Track Selection for the Particle of Interest @@ -158,6 +179,20 @@ struct nuclei_in_jets { if (TMath::Abs(track.dcaZ()) > max_dcaz) return false; + // Rapidity Cut + double mass(0); + if (particle_of_interest == 0) + mass = 0.93827208816; // Proton + if (particle_of_interest == 1) + mass = 1.87561294257; // Deuteron + if (particle_of_interest == 2) + mass = 2.80839160743; // Helium-3 + + TLorentzVector lorentzVect; + lorentzVect.SetXYZM(track.px(), track.py(), track.pz(), mass); + if (lorentzVect.Rapidity() < min_y || lorentzVect.Rapidity() > max_y) + return false; + return true; } @@ -249,14 +284,18 @@ struct nuclei_in_jets { // Process Data void processData(SelectedCollisions::iterator const& collision, FullTracks const& tracks) { - // Event Counter (before event selection) + + // Seed + gRandom->SetSeed(0); + + // Event Counter: before event selection registryQC.fill(HIST("number_of_events_data"), 0.5); // Event Selection if (!collision.sel8()) return; - // Event Counter (after event selection) + // Event Counter: after event selection registryQC.fill(HIST("number_of_events_data"), 1.5); // Reduced Event @@ -296,9 +335,10 @@ struct nuclei_in_jets { particle_ID.push_back(i); } - // Skip Events with no trigger Particle + // Event Counter: Skip Events with no trigger Particle (pmax=0) if (pt_max == 0) return; + registryQC.fill(HIST("number_of_events_data"), 2.5); // Histogram with pt_leading registryQC.fill(HIST("pt_leading"), pt_max); @@ -306,29 +346,25 @@ struct nuclei_in_jets { // Number of Stored Particles int nParticles = static_cast(particle_ID.size()); - // Selection of Events with pt > pt_leading - if (nParticles < 2) + // Event Counter: Skip Events with less than 2 Particles + if (nParticles < 3) return; + registryQC.fill(HIST("number_of_events_data"), 3.5); + + // Event Counter: Skip Events with pt pt_max selection) - registryQC.fill(HIST("number_of_events_data"), 2.5); - - // Skip Events with no Particle of Interest + // Event Counter: Skip Events with no Particle of Interest if (!containsParticleOfInterest) return; - - // Event Counter (events with pt > pt_max that contain particle of interest) - registryQC.fill(HIST("number_of_events_data"), 3.5); + registryQC.fill(HIST("number_of_events_data"), 5.5); // Momentum of the Leading Particle auto const& leading_track = tracks.iteratorAt(leading_ID); TVector3 p_leading(leading_track.px(), leading_track.py(), leading_track.pz()); - // Instruction to be removed - registryQC.fill(HIST("number_of_events_data"), 4.5); - // Array of Particles inside Jet std::vector jet_particle_ID; jet_particle_ID.push_back(leading_ID); @@ -405,16 +441,53 @@ struct nuclei_in_jets { // Multiplicity inside Jet + UE int nParticlesJetUE = static_cast(jet_particle_ID.size()); + // Event Counter: Skip Events with only 1 Particle inside jet cone + if (nParticlesJetUE < 2) + return; + registryQC.fill(HIST("number_of_events_data"), 6.5); + + // Find Maximum Distance from Jet Axis + float Rmax(0); + + for (int i = 0; i < nParticlesJetUE; i++) { + + const auto& jet_track = tracks.iteratorAt(jet_particle_ID[i]); + TVector3 p_i(jet_track.px(), jet_track.py(), jet_track.pz()); + + float deltaEta = p_i.Eta() - p_leading.Eta(); + float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); + float R = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); + if (R > Rmax) + Rmax = R; + } + + // Event Counter: Skip Events with Rmax=0 + if (Rmax == 0) + return; + registryQC.fill(HIST("number_of_events_data"), 7.5); + + registryQC.fill(HIST("r_max_jet"), Rmax); + + // Event Counter: Skip Events with jet not fully inside acceptance + float eta_jet_axis = p_leading.Eta(); + if ((TMath::Abs(eta_jet_axis) + Rmax) > max_eta) + return; + registryQC.fill(HIST("number_of_events_data"), 8.5); + // Fill Jet Multiplicity - registryQC.fill(HIST("jet_plus_ue_multiplicity"), static_cast(jet_particle_ID.size())); + registryQC.fill(HIST("jet_plus_ue_multiplicity"), nParticlesJetUE); // Perpendicular Cones for UE Estimate - TVector3 z_positive(0.0, 0.0, 1.0); - TVector3 z_negative(0.0, 0.0, -1.0); - TVector3 v1 = (z_positive.Cross(p_leading)).Unit(); - TVector3 v2 = (z_negative.Cross(p_leading)).Unit(); - TVector3 v3 = (p_leading.Cross(v1)).Unit(); - TVector3 v4 = (p_leading.Cross(v2)).Unit(); + TVector3 z(0.0, 0.0, p_leading.Mag()); + TVector3 ue_axis = z.Cross(p_leading); + + double dEta(200); + do { + double angle = gRandom->Uniform(0.0, TMath::TwoPi()); + ue_axis.Rotate(angle, p_leading); + double eta_ue_axis = ue_axis.Eta(); + dEta = (TMath::Abs(eta_ue_axis) + Rmax); + } while (dEta > max_eta); // Store UE std::vector ue_particle_ID; @@ -429,43 +502,24 @@ struct nuclei_in_jets { const auto& ue_track = tracks.iteratorAt(particle_ID[i]); // Variables - float deltaEta1 = ue_track.eta() - v1.Eta(); - float deltaEta2 = ue_track.eta() - v2.Eta(); - float deltaEta3 = ue_track.eta() - v3.Eta(); - float deltaEta4 = ue_track.eta() - v4.Eta(); - - float deltaPhi1 = TVector2::Phi_0_2pi(ue_track.phi() - v1.Phi()); - float deltaPhi2 = TVector2::Phi_0_2pi(ue_track.phi() - v2.Phi()); - float deltaPhi3 = TVector2::Phi_0_2pi(ue_track.phi() - v3.Phi()); - float deltaPhi4 = TVector2::Phi_0_2pi(ue_track.phi() - v4.Phi()); - - float dr1 = TMath::Sqrt(deltaEta1 * deltaEta1 + deltaPhi1 * deltaPhi1); - float dr2 = TMath::Sqrt(deltaEta2 * deltaEta2 + deltaPhi2 * deltaPhi2); - float dr3 = TMath::Sqrt(deltaEta3 * deltaEta3 + deltaPhi3 * deltaPhi3); - float dr4 = TMath::Sqrt(deltaEta4 * deltaEta4 + deltaPhi4 * deltaPhi4); - - registryQC.fill(HIST("eta_phi_ue"), deltaEta1, deltaPhi1); - registryQC.fill(HIST("eta_phi_ue"), deltaEta2, deltaPhi2); - registryQC.fill(HIST("eta_phi_ue"), deltaEta3, deltaPhi3); - registryQC.fill(HIST("eta_phi_ue"), deltaEta4, deltaPhi4); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta1 * deltaEta1 + deltaPhi1 * deltaPhi1)); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta2 * deltaEta2 + deltaPhi2 * deltaPhi2)); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta3 * deltaEta3 + deltaPhi3 * deltaPhi3)); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta4 * deltaEta4 + deltaPhi4 * deltaPhi4)); + float deltaEta = ue_track.eta() - ue_axis.Eta(); + float deltaPhi = TVector2::Phi_0_2pi(ue_track.phi() - ue_axis.Phi()); + float dr = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); // Store Particles in the UE - if (dr1 < max_jet_radius || dr2 < max_jet_radius || dr3 < max_jet_radius || dr4 < max_jet_radius) { + if (dr < Rmax) { + registryQC.fill(HIST("eta_phi_ue"), deltaEta, deltaPhi); + registryQC.fill(HIST("r_ue"), dr); ue_particle_ID.push_back(particle_ID[i]); } } // UE Multiplicity int nParticlesUE = static_cast(ue_particle_ID.size()); - - registryQC.fill(HIST("ue_multiplicity"), static_cast(ue_particle_ID.size()) / 4.0); + registryQC.fill(HIST("ue_multiplicity"), nParticlesUE); // Jet Multiplicity - float jet_Nch = static_cast(jet_particle_ID.size()) - static_cast(ue_particle_ID.size()) / 4.0; + int jet_Nch = nParticlesJetUE - nParticlesUE; registryQC.fill(HIST("jet_multiplicity"), jet_Nch); // Loop over particles inside Jet @@ -476,8 +530,10 @@ struct nuclei_in_jets { float deltaEta = p_i.Eta() - p_leading.Eta(); float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); - registryQC.fill(HIST("eta_phi_jet"), deltaEta, deltaPhi); - registryQC.fill(HIST("r_jet"), TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi)); + if (deltaEta != 0 && deltaPhi != 0) { + registryQC.fill(HIST("eta_phi_jet"), deltaEta, deltaPhi); + registryQC.fill(HIST("r_jet"), TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi)); + } // Track Selection if (!passedTrackSelection(jet_track)) @@ -558,6 +614,94 @@ struct nuclei_in_jets { } // end processData PROCESS_SWITCH(nuclei_in_jets, processData, "Process data", true); + + // MC + void processMC(soa::Join::iterator const& collision, MCTracks const& mcTracks, aod::McParticles& mcParticles, aod::McCollisions const& mcCollisions) + { + + // Event Counter (before event sel) + registryQC.fill(HIST("number_of_events_mc"), 0.5); + + // Event Selection + if (!collision.sel8()) + return; + + // Event Counter (after event sel) + registryQC.fill(HIST("number_of_events_mc"), 1.5); + + for (auto& particle : mcParticles) { + + if (!particle.isPhysicalPrimary()) + continue; + if ((particle.pdgCode() != -2212) && (particle.pdgCode() != -1000010020) && (particle.pdgCode() != -1000020030)) + continue; + if (particle.y() < min_y || particle.y() > max_y) + continue; + + // Fill Histograms + if (particle.pdgCode() == -2212) + registryMC.fill(HIST("antiproton_gen"), particle.pt()); + if (particle.pdgCode() == -1000010020) + registryMC.fill(HIST("antideuteron_gen"), particle.pt()); + if (particle.pdgCode() == -1000020030) + registryMC.fill(HIST("antihelium3_gen"), particle.pt()); + } + + for (auto track : mcTracks) { + + // Get MC Particle + if (!track.has_mcParticle()) + continue; + + const auto particle = track.mcParticle(); + if (!particle.isPhysicalPrimary()) + continue; + if ((particle.pdgCode() != -2212) && (particle.pdgCode() != -1000010020) && (particle.pdgCode() != -1000020030)) + continue; + + if (!track.passedITSRefit()) + continue; + if (!track.passedTPCRefit()) + continue; + + // Track Selection + if (!passedTrackSelection(track)) + continue; + if (require_primVtx_contributor && !(track.isPVContributor())) + continue; + + // Variables + float nsigmaTPCPr = track.tpcNSigmaPr(); + float nsigmaTOFPr = track.tofNSigmaPr(); + float nsigmaTPCDe = track.tpcNSigmaDe(); + float nsigmaTOFDe = track.tofNSigmaDe(); + float nsigmaTPCHe = track.tpcNSigmaHe(); + float pt = track.pt(); + + // Antiproton + if (particle.pdgCode() != -2212) { + if (pt < 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC) + registryMC.fill(HIST("antiproton_rec_tpc"), pt); + if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && track.hasTOF() && nsigmaTOFPr > min_nsigmaTOF && nsigmaTOFPr < max_nsigmaTOF) + registryMC.fill(HIST("antiproton_rec_tof"), pt); + } + + // Antideuteron + if (particle.pdgCode() != -1000010020) { + if (pt < 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC) + registryMC.fill(HIST("antideuteron_rec_tpc"), pt); + if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && track.hasTOF() && nsigmaTOFDe > min_nsigmaTOF && nsigmaTOFDe < max_nsigmaTOF) + registryMC.fill(HIST("antideuteron_rec_tof"), pt); + } + + // Antihelium-3 + if (particle.pdgCode() != -1000020030) { + if (nsigmaTPCHe > min_nsigmaTPC && nsigmaTPCHe < max_nsigmaTPC) + registryMC.fill(HIST("antihelium3_rec_tpc"), 2.0 * pt); + } + } + } + PROCESS_SWITCH(nuclei_in_jets, processMC, "process MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGMM/Mult/Core/include/Axes.h b/PWGMM/Mult/Core/include/Axes.h index 6f676b99309..97af3af6423 100644 --- a/PWGMM/Mult/Core/include/Axes.h +++ b/PWGMM/Mult/Core/include/Axes.h @@ -33,7 +33,8 @@ AxisSpec PtAxisEff = {{0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0 AxisSpec PtAxis_wide = {1041, -0.05, 104.05, ptAxisName.data()}; // Smaller wider-binned Pt AxisSpec FT0CAxis = {1001, -0.5, 1000.5, "FT0C amplitude (arb. units)"}; // FT0C amplitudes AxisSpec FT0AAxis = {3001, -0.5, 3000.5, "FT0A amplitude (arb. units)"}; // FT0A amplitudes -AxisSpec FDDAxis = {3001, -0.5, 3000.5, "FDD amplitude (arb. units)"}; // FDD amplitudes +AxisSpec FDAAxis = {3001, -0.5, 3000.5, "FDA amplitude (arb. units)"}; // FDD amplitudes +AxisSpec FDCAxis = {3001, -0.5, 3000.5, "FDC amplitude (arb. units)"}; // FDD amplitudes AxisSpec RapidityAxis = {102, -10.2, 10.2, "Y"}; // Rapidity AxisSpec ScaleAxis = {121, -0.5, 120.5, "Event scale (GeV)"}; // Event scale AxisSpec MPIAxis = {51, -0.5, 50.5, "N_{MPI}"}; // N_{MPI} diff --git a/PWGMM/Mult/Tasks/dndeta.cxx b/PWGMM/Mult/Tasks/dndeta.cxx index 2b01721338e..ab6fea3300e 100644 --- a/PWGMM/Mult/Tasks/dndeta.cxx +++ b/PWGMM/Mult/Tasks/dndeta.cxx @@ -104,7 +104,7 @@ struct MultiplicityCounter { binnedRegistry.add({EventTimeRes.data(), " ; t (ms); centrality", {HistType::kTH2F, {{1001, -0.1, 100.1}, CentAxis}}}); } - if (doprocessCounting || doprocessCountingNoAmb) { + if (doprocessCountingAmbiguous || doprocessCounting) { inclusiveRegistry.add({EventSelection.data(), ";status;events", {HistType::kTH1F, {{static_cast(EvSelBins::kRejected), 0.5, static_cast(EvSelBins::kRejected) + 0.5}}}}); auto hstat = inclusiveRegistry.get(HIST(EventSelection)); auto* x = hstat->GetXaxis(); @@ -122,7 +122,7 @@ struct MultiplicityCounter { inclusiveRegistry.add({PtEta.data(), " ; p_{T} (GeV/c); #eta", {HistType::kTH2F, {PtAxis, EtaAxis}}}); inclusiveRegistry.add({DCAXYPt.data(), " ; p_{T} (GeV/c) ; DCA_{XY} (cm)", {HistType::kTH2F, {PtAxis, DCAAxis}}}); inclusiveRegistry.add({DCAZPt.data(), " ; p_{T} (GeV/c) ; DCA_{Z} (cm)", {HistType::kTH2F, {PtAxis, DCAAxis}}}); - if (doprocessCounting) { + if (doprocessCountingAmbiguous) { inclusiveRegistry.add({ReassignedDCAXYPt.data(), " ; p_{T} (GeV/c) ; DCA_{XY} (cm)", {HistType::kTH2F, {PtAxis, DCAAxis}}}); inclusiveRegistry.add({ReassignedDCAZPt.data(), " ; p_{T} (GeV/c) ; DCA_{Z} (cm)", {HistType::kTH2F, {PtAxis, DCAAxis}}}); inclusiveRegistry.add({ExtraDCAXYPt.data(), " ; p_{T} (GeV/c) ; DCA_{XY} (cm)", {HistType::kTH2F, {PtAxis, DCAAxis}}}); @@ -135,7 +135,7 @@ struct MultiplicityCounter { } } - if (doprocessCountingCentralityFT0C || doprocessCountingCentralityFT0M || doprocessCountingCentralityFT0CNoAmb || doprocessCountingCentralityFT0MNoAmb) { + if (doprocessCountingAmbiguousCentralityFT0C || doprocessCountingAmbiguousCentralityFT0M || doprocessCountingCentralityFT0C || doprocessCountingCentralityFT0M) { binnedRegistry.add({EventSelection.data(), ";status;centrality;events", {HistType::kTH2F, {{3, 0.5, 3.5}, CentAxis}}}); auto hstat = binnedRegistry.get(HIST(EventSelection)); auto* x = hstat->GetXaxis(); @@ -149,7 +149,7 @@ struct MultiplicityCounter { binnedRegistry.add({PtEta.data(), " ; p_{T} (GeV/c); #eta; centrality", {HistType::kTHnSparseF, {PtAxis, EtaAxis, CentAxis}}}); binnedRegistry.add({DCAXYPt.data(), " ; p_{T} (GeV/c) ; DCA_{XY} (cm); centrality", {HistType::kTHnSparseF, {PtAxis, DCAAxis, CentAxis}}}); binnedRegistry.add({DCAZPt.data(), " ; p_{T} (GeV/c) ; DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {PtAxis, DCAAxis, CentAxis}}}); - if (doprocessCountingCentralityFT0C || doprocessCountingCentralityFT0M) { + if (doprocessCountingAmbiguousCentralityFT0C || doprocessCountingAmbiguousCentralityFT0M) { binnedRegistry.add({ReassignedDCAXYPt.data(), " ; p_{T} (GeV/c) ; DCA_{XY} (cm); centrality", {HistType::kTHnSparseF, {PtAxis, DCAAxis, CentAxis}}}); binnedRegistry.add({ReassignedDCAZPt.data(), " ; p_{T} (GeV/c) ; DCA_{Z} (cm); centrality", {HistType::kTHnSparseF, {PtAxis, DCAAxis, CentAxis}}}); binnedRegistry.add({ExtraDCAXYPt.data(), " ; p_{T} (GeV/c) ; DCA_{XY} (cm); centrality", {HistType::kTHnSparseF, {PtAxis, DCAAxis, CentAxis}}}); @@ -162,7 +162,7 @@ struct MultiplicityCounter { } } - if (doprocessGen || doprocessGenNoAmb) { + if (doprocessGenAmbiguous || doprocessGen) { inclusiveRegistry.add({NtrkZvtxGen.data(), "; N_{trk}; Z_{vtx} (cm); events", {HistType::kTH2F, {MultAxis, ZAxis}}}); inclusiveRegistry.add({NtrkZvtxGen_t.data(), "; N_{part}; Z_{vtx} (cm); events", {HistType::kTH2F, {MultAxis, ZAxis}}}); inclusiveRegistry.add({EtaZvtxGen.data(), "; #eta; Z_{vtx} (cm); tracks", {HistType::kTH2F, {EtaAxis, ZAxis}}}); @@ -182,7 +182,7 @@ struct MultiplicityCounter { inclusiveRegistry.add({EfficiencyMult.data(), " ; N_{gen}; Z_{vtx} (cm)", {HistType::kTH2F, {MultAxis, ZAxis}}}); inclusiveRegistry.add({SplitMult.data(), " ; N_{gen} ; Z_{vtx} (cm)", {HistType::kTH2F, {MultAxis, ZAxis}}}); if (responseStudy) { - inclusiveRegistry.add({MultiResponse.data(), " ; N_{gen}; N_{rec}; N_{PV cont}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDDAxis, FDDAxis, ZAxis}}}); + inclusiveRegistry.add({MultiResponse.data(), " ; N_{gen}; N_{rec}; N_{PV cont}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDAAxis, FDCAxis, ZAxis}}}); } } @@ -196,8 +196,8 @@ struct MultiplicityCounter { x->SetBinLabel(static_cast(EvEffBins::kSelectedPVgt0), EvEffBinLabels[static_cast(EvEffBins::kSelectedPVgt0)].data()); } - if (doprocessGenFT0C || doprocessGenFT0M || doprocessGenFT0Chi || doprocessGenFT0Mhi || - doprocessGenFT0CNoAmb || doprocessGenFT0MNoAmb || doprocessGenFT0ChiNoAmb || doprocessGenFT0MhiNoAmb) { + if (doprocessGenAmbiguousFT0C || doprocessAmbiguousGenFT0M || doprocessGenAmbiguousFT0Chi || doprocessGenAmbiguousFT0Mhi || + doprocessGenFT0CNoAmb || doprocessGenFT0M || doprocessGenFT0Chi || doprocessGenFT0Mhi) { binnedRegistry.add({NtrkZvtxGen.data(), "; N_{trk}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({NtrkZvtxGen_t.data(), "; N_{part}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({EtaZvtxGen.data(), "; #eta; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {EtaAxis, ZAxis, CentAxis}}}); @@ -218,7 +218,7 @@ struct MultiplicityCounter { binnedRegistry.add({EfficiencyMult.data(), " ; N_{gen}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({SplitMult.data(), " ; N_{gen} ; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); if (responseStudy) { - binnedRegistry.add({MultiResponse.data(), " ; N_{gen}; N_{rec}, N_{PV cont}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDDAxis, FDDAxis, ZAxis, CentAxis}}}); + binnedRegistry.add({MultiResponse.data(), " ; N_{gen}; N_{rec}, N_{PV cont}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDAAxis, FDCAxis, ZAxis, CentAxis}}}); } } @@ -232,7 +232,7 @@ struct MultiplicityCounter { x->SetBinLabel(static_cast(EvEffBins::kSelectedPVgt0), EvEffBinLabels[static_cast(EvEffBins::kSelectedPVgt0)].data()); } - if (doprocessTrackEfficiency || doprocessTrackEfficiencyNoAmb) { + if (doprocessTrackEfficiencyAmbiguous || doprocessTrackEfficiency) { inclusiveRegistry.add({PtGen.data(), " ; p_{T} (GeV/c)", {HistType::kTH1F, {PtAxisEff}}}); inclusiveRegistry.add({PtGenNoEtaCut.data(), " ; p_{T} (GeV/c)", {HistType::kTH1F, {PtAxisEff}}}); inclusiveRegistry.add({PtEfficiency.data(), " ; p_{T} (GeV/c)", {HistType::kTH1F, {PtAxisEff}}}); @@ -363,6 +363,33 @@ struct MultiplicityCounter { // PV contributors for INEL>0 (PV) collision sample definition Partition pvContribTracksIUEta1 = (nabs(aod::track::eta) < 1.0f) && ((aod::track::flags & (uint32_t)o2::aod::track::PVContributor) == (uint32_t)o2::aod::track::PVContributor); + template + int countTracks(T const& tracks, float z, float c) + { + auto Ntrks = 0; + for (auto& track : tracks) { + if (std::abs(track.eta()) < estimatorEta) { + ++Ntrks; + } + if constexpr (fillHistos) { + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(EtaZvtx), track.eta(), z, c); + binnedRegistry.fill(HIST(PhiEta), track.phi(), track.eta(), c); + binnedRegistry.fill(HIST(PtEta), track.pt(), track.eta(), c); + binnedRegistry.fill(HIST(DCAXYPt), track.pt(), track.dcaXY(), c); + binnedRegistry.fill(HIST(DCAZPt), track.pt(), track.dcaZ(), c); + } else { + inclusiveRegistry.fill(HIST(EtaZvtx), track.eta(), z); + inclusiveRegistry.fill(HIST(PhiEta), track.phi(), track.eta()); + inclusiveRegistry.fill(HIST(PtEta), track.pt(), track.eta()); + inclusiveRegistry.fill(HIST(DCAXYPt), track.pt(), track.dcaXY()); + inclusiveRegistry.fill(HIST(DCAZPt), track.pt(), track.dcaZ()); + } + } + } + return Ntrks; + } + template void processCountingGeneral( typename C::iterator const& collision, @@ -390,31 +417,14 @@ struct MultiplicityCounter { usedTracksIds.clear(); auto groupPVContrib = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto INELgt0PV = groupPVContrib.size() > 0; - auto Ntrks = 0; - for (auto& track : tracks) { - if (std::abs(track.eta()) < estimatorEta) { - ++Ntrks; - } - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(EtaZvtx), track.eta(), z, c); - binnedRegistry.fill(HIST(PhiEta), track.phi(), track.eta(), c); - binnedRegistry.fill(HIST(PtEta), track.pt(), track.eta(), c); - binnedRegistry.fill(HIST(DCAXYPt), track.pt(), track.dcaXY(), c); - binnedRegistry.fill(HIST(DCAZPt), track.pt(), track.dcaZ(), c); - } else { - inclusiveRegistry.fill(HIST(EtaZvtx), track.eta(), z); - inclusiveRegistry.fill(HIST(PhiEta), track.phi(), track.eta()); - inclusiveRegistry.fill(HIST(PtEta), track.pt(), track.eta()); - inclusiveRegistry.fill(HIST(DCAXYPt), track.pt(), track.dcaXY()); - inclusiveRegistry.fill(HIST(DCAZPt), track.pt(), track.dcaZ()); - } - } + auto Ntrks = countTracks(tracks, z, c); if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(NtrkZvtx), Ntrks, z, c); } else { - if (Ntrks > 0 || groupPVContrib.size() > 0) { - if (groupPVContrib.size() > 0) { + if (Ntrks > 0 || INELgt0PV) { + if (INELgt0PV) { inclusiveRegistry.fill(HIST(EventSelection), static_cast(EvSelBins::kSelectedPVgt0)); } if (Ntrks > 0) { @@ -424,7 +434,7 @@ struct MultiplicityCounter { if (Ntrks > 0) { inclusiveRegistry.fill(HIST(EtaZvtx_gt0), track.eta(), z); } - if (groupPVContrib.size() > 0) { + if (INELgt0PV) { inclusiveRegistry.fill(HIST(EtaZvtx_PVgt0), track.eta(), z); } } @@ -440,55 +450,29 @@ struct MultiplicityCounter { } } - template - void processCountingGeneralwAmbiguous( - typename C::iterator const& collision, - FiTracks const& tracks, - soa::SmallGroups const& atracks) + template + int countTracksAmbiguous(T const& tracks, AT const& atracks, float z, float c) { - float c = -1; - if constexpr (hasRecoCent()) { - if constexpr (C::template contains()) { - c = collision.centFT0C(); - } else if (C::template contains()) { - c = collision.centFT0M(); + auto Ntrks = 0; + for (auto& track : atracks) { + auto otrack = track.template track_as(); + // same filtering for ambiguous as for general + if (!otrack.hasITS()) { + continue; } - binnedRegistry.fill(HIST(EventSelection), 1., c); - } else { - inclusiveRegistry.fill(HIST(EventSelection), static_cast(EvSelBins::kAll)); - } - - if (!useEvSel || (collision.sel8() && collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(EventSelection), 2., c); - } else { - inclusiveRegistry.fill(HIST(EventSelection), static_cast(EvSelBins::kSelected)); + if ((otrack.trackCutFlag() & trackSelectionITS) == 0) { + continue; } - auto z = collision.posZ(); - usedTracksIds.clear(); - - auto groupPVContrib = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - - auto Ntrks = 0; - - for (auto& track : atracks) { - auto otrack = track.track_as(); - // same filtering for ambiguous as for general - if (!otrack.hasITS()) { + if (otrack.hasTPC()) { + if ((otrack.trackCutFlag() & trackSelectionTPC) == 0) { continue; } - if ((otrack.trackCutFlag() & trackSelectionITS) == 0) { - continue; - } - if (otrack.hasTPC()) { - if ((otrack.trackCutFlag() & trackSelectionTPC) == 0) { - continue; - } - } - usedTracksIds.emplace_back(track.trackId()); - if (std::abs(otrack.eta()) < estimatorEta) { - ++Ntrks; - } + } + usedTracksIds.emplace_back(track.trackId()); + if (std::abs(otrack.eta()) < estimatorEta) { + ++Ntrks; + } + if (fillHistos) { if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(EtaZvtx), otrack.eta(), z, c); binnedRegistry.fill(HIST(PhiEta), otrack.phi(), otrack.eta(), c); @@ -502,46 +486,52 @@ struct MultiplicityCounter { inclusiveRegistry.fill(HIST(DCAXYPt), otrack.pt(), track.bestDCAXY()); inclusiveRegistry.fill(HIST(DCAZPt), otrack.pt(), track.bestDCAZ()); } - if (!otrack.has_collision()) { - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(ExtraEtaZvtx), otrack.eta(), z, c); - binnedRegistry.fill(HIST(ExtraPhiEta), otrack.phi(), otrack.eta(), c); - binnedRegistry.fill(HIST(ExtraDCAXYPt), otrack.pt(), track.bestDCAXY(), c); - binnedRegistry.fill(HIST(ExtraDCAZPt), otrack.pt(), track.bestDCAZ(), c); - } else { - inclusiveRegistry.fill(HIST(ExtraEtaZvtx), otrack.eta(), z); - inclusiveRegistry.fill(HIST(ExtraPhiEta), otrack.phi(), otrack.eta()); - inclusiveRegistry.fill(HIST(ExtraDCAXYPt), otrack.pt(), track.bestDCAXY()); - inclusiveRegistry.fill(HIST(ExtraDCAZPt), otrack.pt(), track.bestDCAZ()); - } - } else if (otrack.collisionId() != track.bestCollisionId()) { - usedTracksIdsDF.emplace_back(track.trackId()); + } + if (otrack.collisionId() != track.bestCollisionId()) { + usedTracksIdsDF.emplace_back(track.trackId()); + if constexpr (fillHistos) { if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(ReassignedEtaZvtx), otrack.eta(), z, c); binnedRegistry.fill(HIST(ReassignedPhiEta), otrack.phi(), otrack.eta(), c); - binnedRegistry.fill(HIST(ReassignedZvtxCorr), otrack.collision_as().posZ(), z, c); + binnedRegistry.fill(HIST(ReassignedZvtxCorr), otrack.template collision_as().posZ(), z, c); binnedRegistry.fill(HIST(ReassignedDCAXYPt), otrack.pt(), track.bestDCAXY(), c); binnedRegistry.fill(HIST(ReassignedDCAZPt), otrack.pt(), track.bestDCAZ(), c); } else { inclusiveRegistry.fill(HIST(ReassignedEtaZvtx), otrack.eta(), z); inclusiveRegistry.fill(HIST(ReassignedPhiEta), otrack.phi(), otrack.eta()); - inclusiveRegistry.fill(HIST(ReassignedZvtxCorr), otrack.collision_as().posZ(), z); + inclusiveRegistry.fill(HIST(ReassignedZvtxCorr), otrack.template collision_as().posZ(), z); inclusiveRegistry.fill(HIST(ReassignedDCAXYPt), otrack.pt(), track.bestDCAXY()); inclusiveRegistry.fill(HIST(ReassignedDCAZPt), otrack.pt(), track.bestDCAZ()); } } + } else if (!otrack.has_collision()) { + if constexpr (fillHistos) { + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(ExtraEtaZvtx), otrack.eta(), z, c); + binnedRegistry.fill(HIST(ExtraPhiEta), otrack.phi(), otrack.eta(), c); + binnedRegistry.fill(HIST(ExtraDCAXYPt), otrack.pt(), track.bestDCAXY(), c); + binnedRegistry.fill(HIST(ExtraDCAZPt), otrack.pt(), track.bestDCAZ(), c); + } else { + inclusiveRegistry.fill(HIST(ExtraEtaZvtx), otrack.eta(), z); + inclusiveRegistry.fill(HIST(ExtraPhiEta), otrack.phi(), otrack.eta()); + inclusiveRegistry.fill(HIST(ExtraDCAXYPt), otrack.pt(), track.bestDCAXY()); + inclusiveRegistry.fill(HIST(ExtraDCAZPt), otrack.pt(), track.bestDCAZ()); + } + } } + } - for (auto& track : tracks) { - if (std::find(usedTracksIds.begin(), usedTracksIds.end(), track.globalIndex()) != usedTracksIds.end()) { - continue; - } - if (std::find(usedTracksIdsDF.begin(), usedTracksIdsDF.end(), track.globalIndex()) != usedTracksIdsDF.end()) { - continue; - } - if (std::abs(track.eta()) < estimatorEta) { - ++Ntrks; - } + for (auto& track : tracks) { + if (std::find(usedTracksIds.begin(), usedTracksIds.end(), track.globalIndex()) != usedTracksIds.end()) { + continue; + } + if (std::find(usedTracksIdsDF.begin(), usedTracksIdsDF.end(), track.globalIndex()) != usedTracksIdsDF.end()) { + continue; + } + if (std::abs(track.eta()) < estimatorEta) { + ++Ntrks; + } + if constexpr (fillHistos) { if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(EtaZvtx), track.eta(), z, c); binnedRegistry.fill(HIST(PhiEta), track.phi(), track.eta(), c); @@ -556,11 +546,46 @@ struct MultiplicityCounter { inclusiveRegistry.fill(HIST(DCAZPt), track.pt(), track.dcaZ()); } } + } + return Ntrks; + } + + template + void processCountingGeneralwAmbiguous( + typename C::iterator const& collision, + FiTracks const& tracks, + soa::SmallGroups const& atracks) + { + float c = -1; + if constexpr (hasRecoCent()) { + if constexpr (C::template contains()) { + c = collision.centFT0C(); + } else if (C::template contains()) { + c = collision.centFT0M(); + } + binnedRegistry.fill(HIST(EventSelection), 1., c); + } else { + inclusiveRegistry.fill(HIST(EventSelection), static_cast(EvSelBins::kAll)); + } + + if (!useEvSel || (collision.sel8() && collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(EventSelection), 2., c); + } else { + inclusiveRegistry.fill(HIST(EventSelection), static_cast(EvSelBins::kSelected)); + } + auto z = collision.posZ(); + usedTracksIds.clear(); + + auto groupPVContrib = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto INELgt0PV = groupPVContrib.size() > 0; + + auto Ntrks = countTracksAmbiguous(tracks, atracks, z, c); if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(NtrkZvtx), Ntrks, z, c); } else { - if (Ntrks > 0 || groupPVContrib.size() > 0) { - if (groupPVContrib.size() > 0) { + if (Ntrks > 0 || INELgt0PV) { + if (INELgt0PV) { inclusiveRegistry.fill(HIST(EventSelection), static_cast(EvSelBins::kSelectedPVgt0)); } if (Ntrks > 0) { @@ -570,7 +595,7 @@ struct MultiplicityCounter { if (Ntrks > 0) { inclusiveRegistry.fill(HIST(EtaZvtx_gt0), track.track_as().eta(), z); } - if (groupPVContrib.size() > 0) { + if (INELgt0PV) { inclusiveRegistry.fill(HIST(EtaZvtx_PVgt0), track.track_as().eta(), z); } } @@ -584,7 +609,7 @@ struct MultiplicityCounter { if (Ntrks > 0) { inclusiveRegistry.fill(HIST(EtaZvtx_gt0), track.eta(), z); } - if (groupPVContrib.size() > 0) { + if (INELgt0PV) { inclusiveRegistry.fill(HIST(EtaZvtx_PVgt0), track.eta(), z); } } @@ -600,7 +625,7 @@ struct MultiplicityCounter { } } - void processCounting( + void processCountingAmbiguous( ExCols::iterator const& collision, FiTracks const& tracks, soa::SmallGroups const& atracks) @@ -608,19 +633,19 @@ struct MultiplicityCounter { processCountingGeneralwAmbiguous(collision, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processCounting, "Count tracks", false); + PROCESS_SWITCH(MultiplicityCounter, processCountingAmbiguous, "Count tracks", false); - void processCountingNoAmb( + void processCounting( ExCols::iterator const& collision, FiTracks const& tracks) { processCountingGeneral(collision, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processCountingNoAmb, "Count tracks w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processCounting, "Count tracks w/o ambiguous", false); using ExColsCentFT0C = soa::Join; - void processCountingCentralityFT0C( + void processCountingAmbiguousCentralityFT0C( ExColsCentFT0C::iterator const& collision, FiTracks const& tracks, soa::SmallGroups const& atracks) @@ -628,19 +653,19 @@ struct MultiplicityCounter { processCountingGeneralwAmbiguous(collision, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processCountingCentralityFT0C, "Count tracks in FT0C centrality bins", false); + PROCESS_SWITCH(MultiplicityCounter, processCountingAmbiguousCentralityFT0C, "Count tracks in FT0C centrality bins", false); - void processCountingCentralityFT0CNoAmb( + void processCountingCentralityFT0C( ExColsCentFT0C::iterator const& collision, FiTracks const& tracks) { processCountingGeneral(collision, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processCountingCentralityFT0CNoAmb, "Count tracks in FT0C centrality bins w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processCountingCentralityFT0C, "Count tracks in FT0C centrality bins w/o ambiguous", false); using ExColsCentFT0M = soa::Join; - void processCountingCentralityFT0M( + void processCountingAmbiguousCentralityFT0M( ExColsCentFT0M::iterator const& collision, FiTracks const& tracks, soa::SmallGroups const& atracks) @@ -648,16 +673,16 @@ struct MultiplicityCounter { processCountingGeneralwAmbiguous(collision, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processCountingCentralityFT0M, "Count tracks in FT0M centrality bins", false); + PROCESS_SWITCH(MultiplicityCounter, processCountingAmbiguousCentralityFT0M, "Count tracks in FT0M centrality bins", false); - void processCountingCentralityFT0MNoAmb( + void processCountingCentralityFT0M( ExColsCentFT0M::iterator const& collision, FiTracks const& tracks) { processCountingGeneral(collision, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processCountingCentralityFT0MNoAmb, "Count tracks in FT0M centrality bins w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processCountingCentralityFT0M, "Count tracks in FT0M centrality bins w/o ambiguous", false); using Particles = soa::Filtered; using LabeledTracksEx = soa::Join; @@ -665,6 +690,16 @@ struct MultiplicityCounter { using ParticlesI = soa::Filtered>; expressions::Filter primaries = ncheckbit(aod::mcparticle::flags, (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary); + bool isChargedParticle(int code) + { + auto p = pdg->GetParticle(code); + auto charge = 0.; + if (p != nullptr) { + charge = p->Charge(); + } + return std::abs(charge) >= 3.; + } + template void processTrackEfficiencyIndexedGeneral( typename soa::Join::iterator const& collision, @@ -681,12 +716,7 @@ struct MultiplicityCounter { auto sample = particles.sliceByCached(aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); for (auto& particle : sample) { - auto charge = 0.; - auto p = pdg->GetParticle(particle.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 3.) { + if (!isChargedParticle(particle.pdgCode())) { continue; } inclusiveRegistry.fill(HIST(PtGenIdxNoEtaCut), particle.pt()); @@ -858,12 +888,7 @@ struct MultiplicityCounter { } for (auto& particle : particlesPerCol) { - auto charge = 0.; - auto p = pdg->GetParticle(particle.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 3.) { + if (!isChargedParticle(particle.pdgCode())) { continue; } inclusiveRegistry.fill(HIST(PtGenNoEtaCut), particle.pt()); @@ -933,12 +958,7 @@ struct MultiplicityCounter { } for (auto& particle : particlesPerCol) { - auto charge = 0.; - auto p = pdg->GetParticle(particle.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 3.) { + if (!isChargedParticle(particle.pdgCode())) { continue; } inclusiveRegistry.fill(HIST(PtGenNoEtaCut), particle.pt()); @@ -957,7 +977,7 @@ struct MultiplicityCounter { } } - void processTrackEfficiency( + void processTrackEfficiencyAmbiguous( soa::Join::iterator const& collision, aod::McCollisions const& mccollisions, Particles const& mcParticles, FiLTracks const& filtracks, @@ -966,9 +986,9 @@ struct MultiplicityCounter { processTrackEfficiencyGeneralAmbiguous(collision, mccollisions, mcParticles, filtracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processTrackEfficiency, "Calculate tracking efficiency vs pt", false); + PROCESS_SWITCH(MultiplicityCounter, processTrackEfficiencyAmbiguous, "Calculate tracking efficiency vs pt", false); - void processTrackEfficiencyNoAmb( + void processTrackEfficiency( soa::Join::iterator const& collision, aod::McCollisions const& mccollisions, Particles const& mcParticles, FiLTracks const& filtracks) @@ -976,7 +996,7 @@ struct MultiplicityCounter { processTrackEfficiencyGeneral(collision, mccollisions, mcParticles, filtracks); } - PROCESS_SWITCH(MultiplicityCounter, processTrackEfficiencyNoAmb, "Calculate tracking efficiency vs pt w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processTrackEfficiency, "Calculate tracking efficiency vs pt w/o ambiguous", false); template void fillFIT(CIT const& collision, std::vector& ft0as, std::vector& ft0cs, std::vector& fddas, std::vector& fddcs) @@ -1015,52 +1035,46 @@ struct MultiplicityCounter { } } - template - void countParticles(Ps const& particles, MCIT const& mcCollision, int const nCharged, HistogramRegistry& binnedRegistry, HistogramRegistry& inclusiveRegistry, float c_gen, - bool const atLeastOne, - bool const atLeastOne_gt0, - bool const atLeastOne_PVgt0) + template + void fillParticleHistos(Ps const& particles, float z, + int const nCharged, float c, + bool const atLeastOne, bool const atLeastOne_gt0, bool const atLeastOne_PVgt0) { for (auto& particle : particles) { - auto p = pdg->GetParticle(particle.pdgCode()); - auto charge = 0.; - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 3.) { + if (!isChargedParticle(particle.pdgCode())) { continue; } - if constexpr (hasRecoCent) { - binnedRegistry.fill(HIST(EtaZvtxGen_t), particle.eta(), mcCollision.posZ(), c_gen); - binnedRegistry.fill(HIST(PtEtaGen), particle.pt(), particle.eta(), c_gen); + if constexpr (hasCent) { + binnedRegistry.fill(HIST(EtaZvtxGen_t), particle.eta(), z, c); + binnedRegistry.fill(HIST(PtEtaGen), particle.pt(), particle.eta(), c); } else { - inclusiveRegistry.fill(HIST(EtaZvtxGen_t), particle.eta(), mcCollision.posZ()); + inclusiveRegistry.fill(HIST(EtaZvtxGen_t), particle.eta(), z); inclusiveRegistry.fill(HIST(PtEtaGen), particle.pt(), particle.eta()); } if (nCharged > 0) { - if constexpr (hasRecoCent) { - binnedRegistry.fill(HIST(EtaZvtxGen_gt0t), particle.eta(), mcCollision.posZ(), c_gen); + if constexpr (hasCent) { + binnedRegistry.fill(HIST(EtaZvtxGen_gt0t), particle.eta(), z, c); } else { - inclusiveRegistry.fill(HIST(EtaZvtxGen_gt0t), particle.eta(), mcCollision.posZ()); + inclusiveRegistry.fill(HIST(EtaZvtxGen_gt0t), particle.eta(), z); } } if (atLeastOne) { - if constexpr (hasRecoCent) { - binnedRegistry.fill(HIST(EtaZvtxGen), particle.eta(), mcCollision.posZ(), c_gen); + if constexpr (hasCent) { + binnedRegistry.fill(HIST(EtaZvtxGen), particle.eta(), z, c); if (atLeastOne_gt0) { - binnedRegistry.fill(HIST(EtaZvtxGen_gt0), particle.eta(), mcCollision.posZ(), c_gen); + binnedRegistry.fill(HIST(EtaZvtxGen_gt0), particle.eta(), z, c); } if (atLeastOne_PVgt0) { - binnedRegistry.fill(HIST(EtaZvtxGen_PVgt0), particle.eta(), mcCollision.posZ(), c_gen); + binnedRegistry.fill(HIST(EtaZvtxGen_PVgt0), particle.eta(), z, c); } - binnedRegistry.fill(HIST(PhiEtaGen), particle.phi(), particle.eta(), c_gen); + binnedRegistry.fill(HIST(PhiEtaGen), particle.phi(), particle.eta(), c); } else { - inclusiveRegistry.fill(HIST(EtaZvtxGen), particle.eta(), mcCollision.posZ()); + inclusiveRegistry.fill(HIST(EtaZvtxGen), particle.eta(), z); if (atLeastOne_gt0) { - inclusiveRegistry.fill(HIST(EtaZvtxGen_gt0), particle.eta(), mcCollision.posZ()); + inclusiveRegistry.fill(HIST(EtaZvtxGen_gt0), particle.eta(), z); } if (atLeastOne_PVgt0) { - inclusiveRegistry.fill(HIST(EtaZvtxGen_PVgt0), particle.eta(), mcCollision.posZ()); + inclusiveRegistry.fill(HIST(EtaZvtxGen_PVgt0), particle.eta(), z); } inclusiveRegistry.fill(HIST(PhiEtaGen), particle.phi(), particle.eta()); } @@ -1068,6 +1082,22 @@ struct MultiplicityCounter { } } + template + int countParticles(Ps const& particles) + { + auto nCharged = 0; + for (auto& particle : particles) { + if (!isChargedParticle(particle.pdgCode())) { + continue; + } + if (std::abs(particle.eta()) >= estimatorEta) { + continue; + } + nCharged++; + } + return nCharged; + } + template void processGenGeneralAmbiguous( typename MC::iterator const& mcCollision, @@ -1080,21 +1110,7 @@ struct MultiplicityCounter { c_gen = mcCollision.centrality(); } - auto nCharged = 0; - for (auto& particle : particles) { - auto charge = 0.; - auto p = pdg->GetParticle(particle.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 3.) { - continue; - } - if (std::abs(particle.eta()) >= estimatorEta) { - continue; - } - nCharged++; - } + auto nCharged = countParticles(particles); if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ(), c_gen); binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen), c_gen); @@ -1116,7 +1132,6 @@ struct MultiplicityCounter { auto moreThanOne = 0; LOGP(debug, "MC col {} has {} reco cols", mcCollision.globalIndex(), collisions.size()); - auto Nrec = 0; std::vector NrecPerCol; std::vector c_recPerCol; std::vector NPVPerCol; @@ -1140,8 +1155,13 @@ struct MultiplicityCounter { inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kRec)); } if (!useEvSel || (collision.sel8() && collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - Nrec = 0; + auto z = collision.posZ(); ++moreThanOne; + if constexpr (hasRecoCent() && !hasSimCent()) { + if (!atLeastOne) { + c_gen = c_rec; // if there is no generator centrality info, fall back to reco (from the first reco collision) + } + } atLeastOne = true; auto groupPVcontrib = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -1155,28 +1175,8 @@ struct MultiplicityCounter { } auto perCollisionASample = atracks.sliceBy(perColU, collision.globalIndex()); - for (auto const& track : perCollisionASample) { - auto otrack = track.template track_as(); - usedTracksIds.emplace_back(track.trackId()); - if (otrack.collisionId() != track.bestCollisionId()) { - usedTracksIdsDFMC.emplace_back(track.trackId()); - } - if (std::abs(otrack.eta()) < estimatorEta) { - ++Nrec; - } - } auto perCollisionSample = tracks.sliceBy(perCol, collision.globalIndex()); - for (auto const& track : perCollisionSample) { - if (std::find(usedTracksIds.begin(), usedTracksIds.end(), track.globalIndex()) != usedTracksIds.end()) { - continue; - } - if (std::find(usedTracksIdsDFMC.begin(), usedTracksIdsDFMC.end(), track.globalIndex()) != usedTracksIdsDFMC.end()) { - continue; - } - if (std::abs(track.eta()) < estimatorEta) { - ++Nrec; - } - } + auto Nrec = countTracksAmbiguous(perCollisionSample, perCollisionASample, z, c_rec); NrecPerCol.emplace_back(Nrec); NPVPerCol.emplace_back(collision.numContrib()); if (responseStudy) { @@ -1239,7 +1239,8 @@ struct MultiplicityCounter { } } - countParticles()>(particles, mcCollision, nCharged, binnedRegistry, inclusiveRegistry, c_gen, atLeastOne, atLeastOne_gt0, atLeastOne_PVgt0); + auto zmc = mcCollision.posZ(); + fillParticleHistos()>(particles, zmc, nCharged, c_gen, atLeastOne, atLeastOne_gt0, atLeastOne_PVgt0); } template @@ -1254,21 +1255,7 @@ struct MultiplicityCounter { c_gen = mcCollision.centrality(); } - auto nCharged = 0; - for (auto& particle : particles) { - auto charge = 0.; - auto p = pdg->GetParticle(particle.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 3.) { - continue; - } - if (std::abs(particle.eta()) >= estimatorEta) { - continue; - } - nCharged++; - } + auto nCharged = countParticles(particles); if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ(), c_gen); binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen), c_gen); @@ -1290,7 +1277,6 @@ struct MultiplicityCounter { auto moreThanOne = 0; LOGP(debug, "MC col {} has {} reco cols", mcCollision.globalIndex(), collisions.size()); - auto Nrec = 0; std::vector NrecPerCol; std::vector c_recPerCol; std::vector NPVPerCol; @@ -1314,8 +1300,13 @@ struct MultiplicityCounter { inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kRec)); } if (!useEvSel || (collision.sel8() && collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - Nrec = 0; + auto z = collision.posZ(); ++moreThanOne; + if constexpr (hasRecoCent() && !hasSimCent()) { + if (!atLeastOne) { + c_gen = c_rec; // if there is no generator centrality info, fall back to reco (from the first reco collision) + } + } atLeastOne = true; auto groupPVcontrib = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -1329,11 +1320,7 @@ struct MultiplicityCounter { } auto perCollisionSample = tracks.sliceBy(perCol, collision.globalIndex()); - for (auto const& track : perCollisionSample) { - if (std::abs(track.eta()) < estimatorEta) { - ++Nrec; - } - } + auto Nrec = countTracks(perCollisionSample, z, c_rec); NrecPerCol.emplace_back(Nrec); NPVPerCol.emplace_back(collision.numContrib()); if (responseStudy) { @@ -1395,12 +1382,12 @@ struct MultiplicityCounter { inclusiveRegistry.fill(HIST(NotFoundZvtx), mcCollision.posZ()); } } - - countParticles()>(particles, mcCollision, nCharged, binnedRegistry, inclusiveRegistry, c_gen, atLeastOne, atLeastOne_gt0, atLeastOne_PVgt0); + auto zmc = mcCollision.posZ(); + fillParticleHistos()>(particles, zmc, nCharged, c_gen, atLeastOne, atLeastOne_gt0, atLeastOne_PVgt0); } using MC = aod::McCollisions; // soa::Join; - void processGen( + void processGenAmbiguous( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, FiReTracks const& atracks, aod::FT0s const&, aod::FDDs const&) @@ -1408,9 +1395,9 @@ struct MultiplicityCounter { processGenGeneralAmbiguous(mcCollision, collisions, particles, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processGen, "Process generator-level info", false); + PROCESS_SWITCH(MultiplicityCounter, processGenAmbiguous, "Process generator-level info", false); - void processGenNoAmb( + void processGen( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, aod::FT0s const&, aod::FDDs const&) @@ -1418,9 +1405,9 @@ struct MultiplicityCounter { processGenGeneral(mcCollision, collisions, particles, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenNoAmb, "Process generator-level info w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processGen, "Process generator-level info w/o ambiguous", false); - void processGenFT0C( + void processGenAmbiguousFT0C( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, FiReTracks const& atracks, aod::FT0s const&, aod::FDDs const&) @@ -1428,7 +1415,7 @@ struct MultiplicityCounter { processGenGeneralAmbiguous(mcCollision, collisions, particles, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0C, "Process generator-level info (FT0C centrality)", false); + PROCESS_SWITCH(MultiplicityCounter, processGenAmbiguousFT0C, "Process generator-level info (FT0C centrality)", false); void processGenFT0CNoAmb( MC::iterator const& mcCollision, @@ -1440,7 +1427,7 @@ struct MultiplicityCounter { PROCESS_SWITCH(MultiplicityCounter, processGenFT0CNoAmb, "Process generator-level info (FT0C centrality) w/o ambiguous", false); - void processGenFT0M( + void processAmbiguousGenFT0M( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, FiReTracks const& atracks, aod::FT0s const&, aod::FDDs const&) @@ -1448,9 +1435,9 @@ struct MultiplicityCounter { processGenGeneralAmbiguous(mcCollision, collisions, particles, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0M, "Process generator-level info (FT0M centrality)", false); + PROCESS_SWITCH(MultiplicityCounter, processAmbiguousGenFT0M, "Process generator-level info (FT0M centrality)", false); - void processGenFT0MNoAmb( + void processGenFT0M( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, aod::FT0s const&, aod::FDDs const&) @@ -1458,11 +1445,11 @@ struct MultiplicityCounter { processGenGeneral(mcCollision, collisions, particles, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0MNoAmb, "Process generator-level info (FT0M centrality) w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processGenFT0M, "Process generator-level info (FT0M centrality) w/o ambiguous", false); using MChi = soa::Join; - void processGenFT0Chi( + void processGenAmbiguousFT0Chi( MChi::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, FiReTracks const& atracks, aod::FT0s const&, aod::FDDs const&) @@ -1470,9 +1457,9 @@ struct MultiplicityCounter { processGenGeneralAmbiguous(mcCollision, collisions, particles, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0Chi, "Process generator-level info (FT0C centrality, HI)", false); + PROCESS_SWITCH(MultiplicityCounter, processGenAmbiguousFT0Chi, "Process generator-level info (FT0C centrality, HI)", false); - void processGenFT0ChiNoAmb( + void processGenFT0Chi( MChi::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, aod::FT0s const&, aod::FDDs const&) @@ -1480,9 +1467,9 @@ struct MultiplicityCounter { processGenGeneral(mcCollision, collisions, particles, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0ChiNoAmb, "Process generator-level info (FT0C centrality, HI) w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processGenFT0Chi, "Process generator-level info (FT0C centrality, HI) w/o ambiguous", false); - void processGenFT0Mhi( + void processGenAmbiguousFT0Mhi( MChi::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, FiReTracks const& atracks, aod::FT0s const&, aod::FDDs const&) @@ -1490,9 +1477,9 @@ struct MultiplicityCounter { processGenGeneralAmbiguous(mcCollision, collisions, particles, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0Mhi, "Process generator-level info (FT0M centrality, HI)", false); + PROCESS_SWITCH(MultiplicityCounter, processGenAmbiguousFT0Mhi, "Process generator-level info (FT0M centrality, HI)", false); - void processGenFT0MhiNoAmb( + void processGenFT0Mhi( MChi::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, aod::FT0s const&, aod::FDDs const&) @@ -1500,7 +1487,7 @@ struct MultiplicityCounter { processGenGeneral(mcCollision, collisions, particles, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0MhiNoAmb, "Process generator-level info (FT0M centrality, HI) w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processGenFT0Mhi, "Process generator-level info (FT0M centrality, HI) w/o ambiguous", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)