diff --git a/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h b/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h index ac811442471..5189279aae7 100644 --- a/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h +++ b/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h @@ -18,16 +18,71 @@ #ifndef PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_LONGRANGEDERIVED_H_ #define PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_LONGRANGEDERIVED_H_ -#include -#include +#include "Common/DataModel/Multiplicity.h" -#include +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" namespace o2::aod { +namespace lrcorrmccolltable +{ +DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); +} // namespace lrcorrmccolltable +DECLARE_SOA_TABLE(LRMcCollisions, "AOD", "LRMCCOLLISION", + o2::soa::Index<>, + mccollision::PosZ, + lrcorrmccolltable::Multiplicity, + mult::MultMCFT0A, + mult::MultMCFT0C); +using LRMcCollision = LRMcCollisions::iterator; + +namespace lrcorrmctrktable +{ +DECLARE_SOA_INDEX_COLUMN(LRMcCollision, lrMcCollision); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(Phi, phi, float); +} // namespace lrcorrmctrktable + +DECLARE_SOA_TABLE(LRMidMcTracks, "AOD", "LRMIDMCTRACK", + o2::soa::Index<>, + lrcorrmctrktable::LRMcCollisionId, + lrcorrmctrktable::Pt, + lrcorrmctrktable::Eta, + lrcorrmctrktable::Phi, + mcparticle::PdgCode, + mcparticle::Flags, + mcparticle::IsPhysicalPrimary); +using LRMidMcTrack = LRMidMcTracks::iterator; + +DECLARE_SOA_TABLE(LRFt0aMcTracks, "AOD", "LRFT0AMCTRACK", + o2::soa::Index<>, + lrcorrmctrktable::LRMcCollisionId, + lrcorrmctrktable::Pt, + lrcorrmctrktable::Eta, + lrcorrmctrktable::Phi); +using LRFt0aMcTrack = LRFt0aMcTracks::iterator; + +DECLARE_SOA_TABLE(LRFt0cMcTracks, "AOD", "LRFT0CMCTRACK", + o2::soa::Index<>, + lrcorrmctrktable::LRMcCollisionId, + lrcorrmctrktable::Pt, + lrcorrmctrktable::Eta, + lrcorrmctrktable::Phi); +using LRFt0cMcTrack = LRFt0cMcTracks::iterator; + +DECLARE_SOA_TABLE(LRMftMcTracks, "AOD", "LRMFTMCTRACK", + o2::soa::Index<>, + lrcorrmctrktable::LRMcCollisionId, + lrcorrmctrktable::Pt, + lrcorrmctrktable::Eta, + lrcorrmctrktable::Phi); +using LRMftMcTrack = LRMftMcTracks::iterator; + namespace lrcorrcolltable { -DECLARE_SOA_COLUMN(Zvtx, zvtx, float); +DECLARE_SOA_INDEX_COLUMN(LRMcCollision, lrMcCollision); DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); DECLARE_SOA_COLUMN(Centrality, centrality, float); DECLARE_SOA_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, float); //! sum of amplitudes on A side of FT0 @@ -39,17 +94,22 @@ DECLARE_SOA_COLUMN(GapSide, gapSide, uint8_t); // 0 for side DECLARE_SOA_TABLE(LRCollisions, "AOD", "LRCOLLISION", o2::soa::Index<>, bc::RunNumber, - lrcorrcolltable::Zvtx, + collision::PosZ, lrcorrcolltable::Multiplicity, lrcorrcolltable::Centrality, timestamp::Timestamp); +DECLARE_SOA_TABLE(LRCollLabels, "AOD", "LRCOLLLABEL", + lrcorrcolltable::LRMcCollisionId); using LRCollision = LRCollisions::iterator; +using LRCollLabel = LRCollLabels::iterator; +using LRCollisionsWithLabel = soa::Join; +using LRCollisionWithLabel = LRCollisionsWithLabel::iterator; DECLARE_SOA_TABLE(UpcLRCollisions, "AOD", "UPCLRCOLLISION", o2::soa::Index<>, bc::GlobalBC, bc::RunNumber, - lrcorrcolltable::Zvtx, + collision::PosZ, lrcorrcolltable::Multiplicity, lrcorrcolltable::TotalFT0AmplitudeA, lrcorrcolltable::TotalFT0AmplitudeC, @@ -92,7 +152,8 @@ enum TrackPid { kSpCharge, kSpPion, kSpKaon, - kSpProton + kSpProton, + kNoPid }; enum V0TrackPid { kSpK0short, @@ -210,7 +271,6 @@ DECLARE_SOA_TABLE(UpcLRMftBestTracks, "AOD", "UPCLRMFTBESTTRACK", lrcorrtrktable::Eta, lrcorrtrktable::Phi); using UpcLRMftBestTrack = UpcLRMftBestTracks::iterator; - } // namespace o2::aod #endif // PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_LONGRANGEDERIVED_H_ diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx index e8e97df7a69..25719f7f8f5 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx @@ -16,52 +16,49 @@ /// \since October 28, 2025 #include "PWGCF/Core/CorrelationContainer.h" +#include "PWGCF/Core/PairCuts.h" #include "PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGMM/Mult/DataModel/bestCollisionTable.h" -#include "PWGUD/Core/SGCutParHolder.h" #include "PWGUD/Core/SGSelector.h" -#include "PWGUD/Core/UDHelpers.h" #include "PWGUD/Core/UPCHelpers.h" -#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DetectorsCommonDataFormats/AlignParam.h" +#include "FT0Base/Geometry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include + #include -#include -#include #include -#include #include #include @@ -73,17 +70,10 @@ using namespace o2::aod::fwdtrack; using namespace o2::aod::evsel; using namespace o2::constants::math; +auto static constexpr CintZero = 0; auto static constexpr KminFt0cCell = 96; -auto static constexpr PionTrackN = 1; -auto static constexpr KaonTrackN = 2; -auto static constexpr ProtonTrackN = 3; AxisSpec axisEvent{15, 0.5, 15.5, "#Event", "EventAxis"}; - -enum KindOfParticles { - PIONS, - KAONS, - PROTONS -}; +auto static constexpr KminCharge = 3.0f; enum KindOfV0 { kLambda = 0, @@ -115,6 +105,7 @@ struct LongrangeMaker { Configurable isApplyCentFT0M{"isApplyCentFT0M", false, "Centrality based on FT0A + FT0C"}; Configurable isApplyOccuSelection{"isApplyOccuSelection", false, "Enable occupancy selection"}; Configurable cfgOccuCut{"cfgOccuCut", 1000, "Occupancy selection"}; + Configurable isApplyBestCollIndex{"isApplyBestCollIndex", true, "bestCollIndex"}; } cfgevtsel; struct : ConfigurableGroup { @@ -132,6 +123,7 @@ struct LongrangeMaker { Configurable cfigMftEtaMax{"cfigMftEtaMax", -2.5f, "Maximum MFT eta cut"}; Configurable cfigMftEtaMin{"cfigMftEtaMin", -3.6f, "Minimum MFT eta cut"}; Configurable cfigMftDcaxy{"cfigMftDcaxy", 2.0f, "cut on DCA xy for MFT tracks"}; + Configurable cfigMftDcaz{"cfigMftDcaz", 2.0f, "cut on DCA z for MFT tracks"}; Configurable cfigMftCluster{"cfigMftCluster", 5, "cut on MFT Cluster"}; Configurable useMftPtCut{"useMftPtCut", true, "Choose to apply MFT track pT cut"}; Configurable cfgMftPtCutMin{"cfgMftPtCutMin", 0.f, "minimum accepted MFT track pT"}; @@ -236,7 +228,14 @@ struct LongrangeMaker { cfgSgCuts = (SGCutParHolder)sgCuts; } + Produces lrmccollision; + Produces lrmidmctracks; + Produces lrft0amctracks; + Produces lrft0cmctracks; + Produces lrmftmctracks; + Produces lrcollision; + Produces lrcollisionMcLabel; Produces lrmidtracks; Produces lrft0atracks; Produces lrft0ctracks; @@ -265,7 +264,7 @@ struct LongrangeMaker { void processData(CollTable::iterator const& col, TrksTable const& tracks, aod::FT0s const&, MftTrkTable const& mfttracks, - soa::SmallGroups const& retracks, + soa::SmallGroups const& besttracks, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { if (!isEventSelected(col)) { @@ -284,13 +283,11 @@ struct LongrangeMaker { continue; if (!myTrackFilter.IsSelected(track)) continue; + auto pid = getTrackPID(track); lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpCharge); - if (getTrackPID(track) == PionTrackN) - lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpPion); - if (getTrackPID(track) == KaonTrackN) - lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpKaon); - if (getTrackPID(track) == ProtonTrackN) - lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpProton); + if (pid != aod::lrcorrtrktable::kSpCharge) { + lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), pid); + } } // ft0 loop @@ -304,7 +301,7 @@ struct LongrangeMaker { lrft0atracks(lrcollision.lastIndex(), chanelid, ampl, eta, phi); } for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { - auto chanelid = ft0.channelC()[iCh]; + auto chanelid = ft0.channelC()[iCh] + KminFt0cCell; float ampl = ft0.amplitudeC()[iCh]; auto phi = getPhiFT0(chanelid, 1); auto eta = getEtaFT0(chanelid, 1); @@ -321,12 +318,11 @@ struct LongrangeMaker { lrmfttracks(lrcollision.lastIndex(), track.pt(), track.eta(), phi); } - if (retracks.size() > 0) { - for (const auto& retrack : retracks) { - if (std::abs(retrack.bestDCAXY()) > cfgmfttrksel.cfigMftDcaxy) { - continue; // does not point to PV properly - } - auto track = retrack.mfttrack(); + if (besttracks.size() > 0) { + for (const auto& besttrack : besttracks) { + if (!isMftBestTrackSelected(besttrack)) + continue; + auto track = besttrack.mfttrack(); if (!isMftTrackSelected(track)) { continue; } @@ -373,7 +369,7 @@ struct LongrangeMaker { TrksTable const& tracks, aod::Zdcs const&, aod::FV0As const& fv0as, aod::FT0s const& ft0s, aod::FDDs const& fdds, MftTrkTable const& mfttracks, - soa::SmallGroups const& retracks, + soa::SmallGroups const& besttracks, aod::V0Datas const& V0s) { if (!isEventSelected(col)) { @@ -416,13 +412,11 @@ struct LongrangeMaker { continue; if (!myTrackFilter.IsSelected(track)) continue; + auto pid = getTrackPID(track); upclrmidtracks(upclrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpCharge); - if (getTrackPID(track) == PionTrackN) - upclrmidtracks(upclrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpPion); - if (getTrackPID(track) == KaonTrackN) - upclrmidtracks(upclrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpKaon); - if (getTrackPID(track) == ProtonTrackN) - upclrmidtracks(upclrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpProton); + if (pid != aod::lrcorrtrktable::kSpCharge) { + upclrmidtracks(upclrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), pid); + } } // ft0 loop @@ -436,7 +430,7 @@ struct LongrangeMaker { upclrft0atracks(upclrcollision.lastIndex(), chanelid, ampl, eta, phi); } for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { - auto chanelid = ft0.channelC()[iCh]; + auto chanelid = ft0.channelC()[iCh] + KminFt0cCell; float ampl = ft0.amplitudeC()[iCh]; auto phi = getPhiFT0(chanelid, 1); auto eta = getEtaFT0(chanelid, 1); @@ -453,12 +447,11 @@ struct LongrangeMaker { upclrmfttracks(upclrcollision.lastIndex(), track.pt(), track.eta(), phi); } - if (retracks.size() > 0) { - for (const auto& retrack : retracks) { - if (std::abs(retrack.bestDCAXY()) > cfgmfttrksel.cfigMftDcaxy) { - continue; // does not point to PV properly - } - auto track = retrack.mfttrack(); + if (besttracks.size() > 0) { + for (const auto& besttrack : besttracks) { + if (!isMftBestTrackSelected(besttrack)) + continue; + auto track = besttrack.mfttrack(); if (!isMftTrackSelected(track)) { continue; } @@ -502,6 +495,173 @@ struct LongrangeMaker { } // SG events } + using ColMCTrueTable = soa::Join; + using ColMCRecTable = soa::SmallGroups>; + using TrksMCRecTable = soa::Filtered>; + using MftTrkMCRecTable = soa::Join; + Preslice perColMidtrack = aod::track::collisionId; + Preslice perColMfttrack = o2::aod::fwdtrack::collisionId; + PresliceUnsorted perColMftbesttrack = aod::fwdtrack::bestCollisionId; + + void processMCRec(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols, TrksMCRecTable const& RecTracks, + aod::FT0s const&, MftTrkMCRecTable const& mfttracks, aod::BestCollisionsFwd3d const& besttracks, + aod::McParticles const& mcparticles, aod::BCsWithTimestamps const&) + { + auto multiplicity = 0; + for (const auto& particle : mcparticles) { + if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult) + continue; + multiplicity++; + } + lrmccollision(mcCollision.posZ(), multiplicity, mcCollision.multMCFT0A(), mcCollision.multMCFT0C()); + + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) { + continue; + } + if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + continue; + } + auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); + auto multiplicity = countNTracks(recTracksPart); + auto centrality = selColCent(RecCol); + auto bc = RecCol.bc_as(); + lrcollision(bc.runNumber(), RecCol.posZ(), multiplicity, centrality, bc.timestamp()); + lrcollisionMcLabel(RecCol.mcCollisionId()); + + // track loop + for (const auto& track : recTracksPart) { + if (!track.isGlobalTrack()) + continue; + if (!myTrackFilter.IsSelected(track)) + continue; + if (!track.has_mcParticle()) + continue; + auto mcpart = track.mcParticle(); + if (RecCol.mcCollisionId() != mcpart.mcCollisionId()) + continue; + auto pid = getTrackPID(track); + lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::lrcorrtrktable::kSpCharge); + if (pid != aod::lrcorrtrktable::kSpCharge) { + lrmidtracks(lrcollision.lastIndex(), track.pt(), track.eta(), track.phi(), pid); + } + } + + // ft0 loop + if (RecCol.has_foundFT0()) { + const auto& ft0 = RecCol.foundFT0(); + for (std::size_t iCh = 0; iCh < ft0.channelA().size(); iCh++) { + auto chanelid = ft0.channelA()[iCh]; + float ampl = ft0.amplitudeA()[iCh]; + auto phi = getPhiFT0(chanelid, 0); + auto eta = getEtaFT0(chanelid, 0); + lrft0atracks(lrcollision.lastIndex(), chanelid, ampl, eta, phi); + } + for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { + auto chanelid = ft0.channelC()[iCh] + KminFt0cCell; + float ampl = ft0.amplitudeC()[iCh]; + auto phi = getPhiFT0(chanelid, 1); + auto eta = getEtaFT0(chanelid, 1); + lrft0ctracks(lrcollision.lastIndex(), chanelid, ampl, eta, phi); + } + } + + // mft loop + auto recMftTracksPart = mfttracks.sliceBy(perColMfttrack, RecCol.globalIndex()); + for (const auto& track : recMftTracksPart) { + if (!isMftTrackSelected(track)) + continue; + if (!track.has_mcParticle()) + continue; + auto mcpart = track.mcParticle(); + if (RecCol.mcCollisionId() != mcpart.mcCollisionId()) + continue; + auto phi = track.phi(); + o2::math_utils::bringTo02Pi(phi); + lrmfttracks(lrcollision.lastIndex(), track.pt(), track.eta(), phi); + } + + auto recMftbestTracksPart = besttracks.sliceBy(perColMftbesttrack, RecCol.globalIndex()); + if (recMftbestTracksPart.size() > 0) { + for (const auto& besttrack : recMftbestTracksPart) { + if (!isMftBestTrackSelected(besttrack)) + continue; + auto track = besttrack.mfttrack_as(); + if (!isMftTrackSelected(track)) { + continue; + } + auto phi = track.phi(); + o2::math_utils::bringTo02Pi(phi); + lrmftbesttracks(lrcollision.lastIndex(), track.pt(), track.eta(), phi); + } + } + + for (const auto& particle : mcparticles) { + if (!isGenPartSelected(particle)) { + continue; + } + // Fill midrapidity tracks + if (std::abs(particle.eta()) < cfgtrksel.cfgEtaCut && particle.pt() > cfgtrksel.cfgPtCutMin && particle.pt() < cfgtrksel.cfgPtCutMult) + lrmidmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), particle.flags()); + // Fill FT0 tracks + if (3.5 < particle.eta() && particle.eta() < 4.9) + lrft0amctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi()); + if (-3.3 < particle.eta() && particle.eta() < -2.1) + lrft0cmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi()); + // Fill MFT tracks + if (-3.6 < particle.eta() && particle.eta() < -2.4) + lrmftmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi()); + } + } + } + + void processMCGen(ColMCTrueTable::iterator const& mcCollision, aod::McParticles const& mcparticles) + { + auto multiplicity = 0; + for (const auto& particle : mcparticles) { + if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult) + continue; + multiplicity++; + } + lrmccollision(mcCollision.posZ(), multiplicity, mcCollision.multMCFT0A(), mcCollision.multMCFT0C()); + + for (const auto& particle : mcparticles) { + if (!isGenPartSelected(particle)) { + continue; + } + // Fill midrapidity tracks + if (std::abs(particle.eta()) < cfgtrksel.cfgEtaCut && particle.pt() > cfgtrksel.cfgPtCutMin && particle.pt() < cfgtrksel.cfgPtCutMult) + lrmidmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), particle.flags()); + // Fill FT0 tracks + if (3.5 < particle.eta() && particle.eta() < 4.9) + lrft0amctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi()); + if (-3.3 < particle.eta() && particle.eta() < -2.1) + lrft0cmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi()); + // Fill MFT tracks + if (-3.6 < particle.eta() && particle.eta() < -2.4) + lrmftmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi()); + } + } + + template + bool isGenPartSelected(CheckGenPart const& particle) + { + if (!particle.isPhysicalPrimary()) { + return false; + } + if (!particle.producedByGenerator()) { + return false; + } + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (pdgParticle == nullptr) { + return false; + } + if (std::abs(pdgParticle->Charge()) < KminCharge) { + return false; + } + return true; + } + template bool isEventSelected(CheckCol const& col) { @@ -587,7 +747,7 @@ struct LongrangeMaker { } template - int getTrackPID(TTrack const& track) + aod::lrcorrtrktable::TrackPid getTrackPID(TTrack const& track) { // Computing Nsigma arrays for pion, kaon, and protons std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; @@ -595,7 +755,6 @@ struct LongrangeMaker { std::array nSigmaITS = {itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track)}; std::array nSigmaToUse = isUseItsPid ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS std::vector detectorNsigmaCut = isUseItsPid ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS - int pid = -1; bool isPion, isKaon, isProton; bool isDetectedPion = nSigmaToUse[0] < detectorNsigmaCut[0] && nSigmaToUse[0] > detectorNsigmaCut[0 + 3]; bool isDetectedKaon = nSigmaToUse[1] < detectorNsigmaCut[1] && nSigmaToUse[1] > detectorNsigmaCut[1 + 3]; @@ -606,7 +765,7 @@ struct LongrangeMaker { bool isTofProton = nSigmaTOF[2] < tofNsigmaCut[2] && nSigmaTOF[2] > tofNsigmaCut[2 + 3]; if (track.pt() > cfgTofPidPtCut && !track.hasTOF()) { - return 0; + return aod::lrcorrtrktable::kNoPid; } else if (track.pt() > cfgTofPidPtCut && track.hasTOF()) { isPion = isTofPion && isDetectedPion; isKaon = isTofKaon && isDetectedKaon; @@ -618,20 +777,18 @@ struct LongrangeMaker { } if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { - return 0; // more than one particle satisfy the criteria + return aod::lrcorrtrktable::kNoPid; // more than one particle satisfy the criteria } if (isPion) { - pid = PIONS; + return aod::lrcorrtrktable::kSpPion; } else if (isKaon) { - pid = KAONS; + return aod::lrcorrtrktable::kSpKaon; } else if (isProton) { - pid = PROTONS; + return aod::lrcorrtrktable::kSpProton; } else { - return 0; // no particle satisfies the criteria + return aod::lrcorrtrktable::kNoPid; // no particle satisfies the criteria } - - return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton } double getPhiFT0(uint chno, int i) @@ -670,6 +827,24 @@ struct LongrangeMaker { return true; } + template + bool isMftBestTrackSelected(CheckMftBestTrack const& besttrack) + { + if (besttrack.bestCollisionId() < CintZero) { + return false; + } + if (besttrack.ambDegree() == CintZero) { + return false; + } + if (std::abs(besttrack.bestDCAXY()) > cfgmfttrksel.cfigMftDcaxy) { + return false; + } + if (std::abs(besttrack.bestDCAZ()) >= cfgmfttrksel.cfigMftDcaz) { + return false; + } + return true; + } + template bool isSelectV0Track(const T1& v0) { @@ -768,6 +943,8 @@ struct LongrangeMaker { PROCESS_SWITCH(LongrangeMaker, processData, "process All collisions", false); PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false); + PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false); + PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx index e2ea376768d..d3152e7ee47 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx @@ -60,6 +60,7 @@ struct LongrangecorrDerived { Configurable cfgV0Mask{"cfgV0Mask", 0, "Selection bitmask for the V0 particle"}; Configurable cfgVtxCut{"cfgVtxCut", 10.0f, "Vertex Z range to consider"}; Configurable isUseCentEst{"isUseCentEst", false, "Centrality based classification"}; + Configurable isUseDataLikeMult{"isUseDataLikeMult", 0, "Data like mult/cent classification"}; Configurable cfgFv0Cut{"cfgFv0Cut", 50.0f, "FV0A threshold"}; Configurable cfgFt0aCut{"cfgFt0aCut", 100.0f, "FT0A threshold"}; @@ -100,6 +101,12 @@ struct LongrangecorrDerived { using MftbestTrksTable = aod::LRMftBestTracks; using V0TrksTable = aod::LRV0Tracks; + using McCollsTable = aod::LRMcCollisions; + using McTrksTable = aod::LRMidMcTracks; + using McMftTrksTable = aod::LRMftMcTracks; + using McFt0aTrksTable = aod::LRFt0aMcTracks; + using McFt0cTrksTable = aod::LRFt0cMcTracks; + using UpcCollsTable = soa::Join; using TrksUpcTable = aod::UpcLRMidTracks; using MftTrksUpcTable = aod::UpcLRMftTracks; @@ -122,6 +129,11 @@ struct LongrangecorrDerived { Preslice perUpcColFt0c = aod::lrcorrtrktable::upcLRCollisionId; Preslice perUpcColV0 = aod::lrcorrtrktable::upcLRCollisionId; + Preslice perMcColTpc = aod::lrcorrmctrktable::lrMcCollisionId; + Preslice perMcColMft = aod::lrcorrmctrktable::lrMcCollisionId; + Preslice perMcColFt0a = aod::lrcorrmctrktable::lrMcCollisionId; + Preslice perMcColFt0c = aod::lrcorrmctrktable::lrMcCollisionId; + void init(InitContext const&) { std::vector corrAxis = {{axisVtxZ, "z-vtx (cm)"}, @@ -170,7 +182,7 @@ struct LongrangecorrDerived { if constexpr (std::experimental::is_detected::value) { histos.fill(HIST("hCentrality"), col.centrality()); } - histos.fill(HIST("hVertexZ"), col.zvtx()); + histos.fill(HIST("hVertexZ"), col.posZ()); } template @@ -273,7 +285,7 @@ struct LongrangecorrDerived { template void processSame(TCollision const& col, TTriggers const& triggers, TAssocs const& assocs) { - if (std::abs(col.zvtx()) >= cfgVtxCut) { + if (std::abs(col.posZ()) >= cfgVtxCut) { return; } fillCollQA(col); @@ -286,7 +298,7 @@ struct LongrangecorrDerived { } else { multiplicity = col.multiplicity(); } - fillCorrHist(same, triggers, assocs, false, col.zvtx(), multiplicity, 1.0); + fillCorrHist(same, triggers, assocs, false, col.posZ(), multiplicity, 1.0); } // process same template @@ -311,7 +323,7 @@ struct LongrangecorrDerived { } return multiplicity; }; - using MixedBinning = FlexibleBinningPolicy, aod::lrcorrcolltable::Zvtx, decltype(getMultiplicity)>; + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getMultiplicity)>; MixedBinning binningOnVtxAndMult{{getMultiplicity}, {axisVtxZME, axisMultME}, true}; auto tracksTuple = std::make_tuple(std::forward(tracks)...); using TupleAtrack = std::tuple_element<0, decltype(tracksTuple)>::type; @@ -325,18 +337,60 @@ struct LongrangecorrDerived { } } float eventweight = 1.0f / it.currentWindowNeighbours(); - auto multiplicity = 1.0f; - if constexpr (std::experimental::is_detected::value) { + auto multiplicity = getMultiplicity(col1); + fillCorrHist(mixed, tracks1, tracks2, true, col1.posZ(), multiplicity, eventweight); + } // pair loop + } // process mixed + + template + void processMcSame(McCollsTable::iterator const& mccollision, soa::SmallGroups const& collisions, TTriggers const& triggers, TAssocs const& assocs) + { + if (std::abs(mccollision.posZ()) >= cfgVtxCut) { + return; + } + fillCollQA(mccollision); + auto multiplicity = mccollision.multiplicity(); + if (isUseDataLikeMult > 0) { + for (const auto& collision : collisions) { if (isUseCentEst) - multiplicity = col1.centrality(); + multiplicity = collision.centrality(); else - multiplicity = col1.multiplicity(); - } else { - multiplicity = col1.multiplicity(); + multiplicity = collision.multiplicity(); } - fillCorrHist(mixed, tracks1, tracks2, true, col1.zvtx(), multiplicity, eventweight); + } + fillCorrHist(same, triggers, assocs, false, mccollision.posZ(), multiplicity, 1.0); + } // process MC same + + template + void processMcMixed(McCollsTable const& mccollisions, aod::LRCollisionsWithLabel const& collisions, TrackTypes&&... tracks) + { + bool useMCMultiplicity = (isUseDataLikeMult == 0); + auto getMultiplicity = + [&collisions, &useMCMultiplicity, this](auto& col) { + if (useMCMultiplicity) + return col.multiplicity(); + auto groupedCollisions = collisions.sliceByCached(aod::lrcorrcolltable::lrMcCollisionId, col.globalIndex(), this->cache); + if (groupedCollisions.size() == 0) + return -1.0f; + if (isUseCentEst) + return groupedCollisions.begin().centrality(); + else + return groupedCollisions.begin().multiplicity(); + }; + + using MixedBinning = FlexibleBinningPolicy, aod::mccollision::PosZ, decltype(getMultiplicity)>; + MixedBinning binningOnVtxAndMult{{getMultiplicity}, {axisVtxZME, axisMultME}, true}; + auto tracksTuple = std::make_tuple(std::forward(tracks)...); + using TupleAtrack = std::tuple_element<0, decltype(tracksTuple)>::type; + using TupleBtrack = std::tuple_element - 1, decltype(tracksTuple)>::type; + Pair pairs{binningOnVtxAndMult, cfgNmixedevent, -1, mccollisions, tracksTuple, &cache}; + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [col1, tracks1, col2, tracks2] = *it; + float eventweight = 1.0f / it.currentWindowNeighbours(); + auto multiplicity = getMultiplicity(col1); + fillCorrHist(mixed, tracks1, tracks2, true, col1.posZ(), multiplicity, eventweight); } // pair loop - } // process mixed + } // process MC mixed void processTpcft0aSE(CollsTable::iterator const& col, TrksTable const& tracks, Ft0aTrksTable const& ft0as) { @@ -545,6 +599,46 @@ struct LongrangecorrDerived { processMixed(cols, tracks, mfts); } + void processMcTpcft0aSE(McCollsTable::iterator const& mccollision, soa::SmallGroups const& collisions, McTrksTable const& tracks, McFt0aTrksTable const& ft0as) + { + processMcSame(mccollision, collisions, tracks, ft0as); + } + + void processMcTpcft0cSE(McCollsTable::iterator const& mccollision, soa::SmallGroups const& collisions, McTrksTable const& tracks, McFt0cTrksTable const& ft0cs) + { + processMcSame(mccollision, collisions, tracks, ft0cs); + } + + void processMcTpcmftSE(McCollsTable::iterator const& mccollision, soa::SmallGroups const& collisions, McTrksTable const& tracks, McMftTrksTable const& mfts) + { + processMcSame(mccollision, collisions, tracks, mfts); + } + + void processMcMftft0aSE(McCollsTable::iterator const& mccollision, soa::SmallGroups const& collisions, McMftTrksTable const& mfts, McFt0aTrksTable const& ft0as) + { + processMcSame(mccollision, collisions, mfts, ft0as); + } + + void processMcTpcft0aME(McCollsTable const& mccollisions, aod::LRCollisionsWithLabel const& collisions, McTrksTable const& tracks, McFt0aTrksTable const& ft0as) + { + processMcMixed(mccollisions, collisions, tracks, ft0as); + } + + void processMcTpcft0cME(McCollsTable const& mccollisions, aod::LRCollisionsWithLabel const& collisions, McTrksTable const& tracks, McFt0cTrksTable const& ft0cs) + { + processMcMixed(mccollisions, collisions, tracks, ft0cs); + } + + void processMcTpcmftME(McCollsTable const& mccollisions, aod::LRCollisionsWithLabel const& collisions, McTrksTable const& tracks, McMftTrksTable const& mfts) + { + processMcMixed(mccollisions, collisions, tracks, mfts); + } + + void processMcMftft0aME(McCollsTable const& mccollisions, aod::LRCollisionsWithLabel const& collisions, McMftTrksTable const& mfts, McFt0aTrksTable const& ft0as) + { + processMcMixed(mccollisions, collisions, mfts, ft0as); + } + PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aSE, "same event TPC vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aME, "mixed event TPC vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processTpcft0cSE, "same event TPC vs FT0C", false); @@ -581,6 +675,14 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processUpcMftbestft0aME, "mixed UPC event best MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0mftbestSE, "same UPC event V0 vs best MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0mftbestME, "mixed UPC event V0 vs best MFT", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcTpcft0aSE, "same MC event TPC vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcTpcft0aME, "mixed MC event TPC vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcTpcft0cSE, "same MC event TPC vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcTpcft0cME, "mixed MC event TPC vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcTpcmftSE, "same MC event TPC vs MFT", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcTpcmftME, "mixed MC event TPC vs MFT", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcMftft0aSE, "same MC event MFT vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcMftft0aME, "mixed MC event MFT vs FT0A", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)