diff --git a/PWGLF/DataModel/LFCKSSpinalignmentTables.h b/PWGLF/DataModel/LFCKSSpinalignmentTables.h index 7e6447459cc..6593d22fe6b 100644 --- a/PWGLF/DataModel/LFCKSSpinalignmentTables.h +++ b/PWGLF/DataModel/LFCKSSpinalignmentTables.h @@ -33,6 +33,7 @@ namespace o2::aod namespace kshortpionevent { DECLARE_SOA_COLUMN(Cent, cent, float); +DECLARE_SOA_COLUMN(Posz, posz, float); DECLARE_SOA_COLUMN(CollIndex, collIndex, float); DECLARE_SOA_COLUMN(PsiFT0C, psiFT0C, float); DECLARE_SOA_COLUMN(PsiFT0A, psiFT0A, float); @@ -41,6 +42,7 @@ DECLARE_SOA_COLUMN(PsiTPC, psiTPC, float); DECLARE_SOA_TABLE(KShortpionEvents, "AOD", "KSHORTPIONEVENT", o2::soa::Index<>, kshortpionevent::Cent, + kshortpionevent::Posz, kshortpionevent::CollIndex, kshortpionevent::PsiFT0C, kshortpionevent::PsiFT0A, @@ -63,7 +65,6 @@ DECLARE_SOA_COLUMN(KShortMass, kShortMass, float); //! KShort Ma DECLARE_SOA_COLUMN(PionBachPx, pionBachPx, float); //! Bachelor Pion Px DECLARE_SOA_COLUMN(PionBachPy, pionBachPy, float); //! Bachelor Pion Py DECLARE_SOA_COLUMN(PionBachPz, pionBachPz, float); //! Bachelor Pion Pz -DECLARE_SOA_COLUMN(PionBachSign, pionBachSign, int); //! Bachelor Pion Sign DECLARE_SOA_COLUMN(PionBachTPC, pionBachTPC, float); //! Bachelor Pion nsigmatpc DECLARE_SOA_COLUMN(PionBachTOFHit, pionBachTOFHit, int); //! Bachelor Pion tof hit availability DECLARE_SOA_COLUMN(PionBachTOF, pionBachTOF, float); //! Bachelor Pion nsigmatof @@ -71,7 +72,7 @@ DECLARE_SOA_COLUMN(PionBachIndex, pionBachIndex, int); //! Bachelor DECLARE_SOA_COLUMN(PionIndex1, pionIndex1, int); //! Daughter Pion index1 DECLARE_SOA_COLUMN(PionIndex2, pionIndex2, int); //! Daughter Pion index2 } // namespace kshortpionpair -DECLARE_SOA_TABLE(KShortpionPairs, "AOD", "KSHORTPIONPAIR", +DECLARE_SOA_TABLE(KShortTracks, "AOD", "KSHORTTRACK", o2::soa::Index<>, kshortpionpair::KShortpionEventId, kshortpionpair::V0Cospa, @@ -85,17 +86,23 @@ DECLARE_SOA_TABLE(KShortpionPairs, "AOD", "KSHORTPIONPAIR", kshortpionpair::KShortPy, kshortpionpair::KShortPz, kshortpionpair::KShortMass, + kshortpionpair::PionIndex1, + kshortpionpair::PionIndex2); + +using KShortTrack = KShortTracks::iterator; + +DECLARE_SOA_TABLE(PionTracks, "AOD", "PIONTRACK", + o2::soa::Index<>, + kshortpionpair::KShortpionEventId, kshortpionpair::PionBachPx, kshortpionpair::PionBachPy, kshortpionpair::PionBachPz, - kshortpionpair::PionBachSign, + // kshortpionpair::PionBachSign, kshortpionpair::PionBachTPC, kshortpionpair::PionBachTOFHit, kshortpionpair::PionBachTOF, - kshortpionpair::PionBachIndex, - kshortpionpair::PionIndex1, - kshortpionpair::PionIndex2); + kshortpionpair::PionBachIndex); -using KShortpionPair = KShortpionPairs::iterator; +using PionTrack = PionTracks::iterator; } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFCKSSPINALIGNMENTTABLES_H_ diff --git a/PWGLF/TableProducer/Resonances/cksspinalignment.cxx b/PWGLF/TableProducer/Resonances/cksspinalignment.cxx index 91bb6662dbc..56fc938f43b 100644 --- a/PWGLF/TableProducer/Resonances/cksspinalignment.cxx +++ b/PWGLF/TableProducer/Resonances/cksspinalignment.cxx @@ -60,7 +60,8 @@ using namespace o2::aod::rctsel; struct cksspinalignment { Produces kshortpionEvent; - Produces kshortpionPair; + Produces kshortTrack; + Produces pionTrack; Service ccdb; @@ -279,14 +280,14 @@ struct cksspinalignment { std::vector v0Lifetime = {}; // std::vector armenteros = {}; std::vector pionBachelorIndex = {}; - std::vector pionBachelorSign = {}; + // std::vector pionBachelorSign = {}; std::vector pionBachelorTPC = {}; std::vector pionBachelorTOF = {}; std::vector pionBachelorTOFHit = {}; int numbV0 = 0; auto centrality = collision.centFT0C(); - // auto vz = collision.posZ(); + auto vz = collision.posZ(); int occupancy = collision.trackOccupancyInTimeRange(); auto psiFT0C = collision.psiFT0C(); auto psiFT0A = collision.psiFT0A(); @@ -318,6 +319,8 @@ struct cksspinalignment { auto track1ID = track1.globalIndex(); auto track1sign = track1.sign(); + if (track1sign == 0) + continue; auto track1nsigTPC = track1.tpcNSigmaPi(); auto track1nsigTOF = -999.9; auto track1TOFHit = -1; @@ -327,52 +330,57 @@ struct cksspinalignment { histos.fill(HIST("hTrkSelInfo"), 4.5); } pionbach = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassPionCharged); - for (const auto& v0 : V0s) { - histos.fill(HIST("hV0Info"), 0.5); - auto [kshortTag, isValid] = getK0sTags(v0, collision); - if (kshortTag && isValid) { - histos.fill(HIST("hV0Info"), 1.5); - auto postrack1 = v0.template posTrack_as(); - auto negtrack1 = v0.template negTrack_as(); - positiveIndex.push_back(postrack1.globalIndex()); - negativeIndex.push_back(negtrack1.globalIndex()); - v0Cospa.push_back(v0.v0cosPA()); - v0Radius.push_back(v0.v0radius()); - dcaPositive.push_back(std::abs(v0.dcapostopv())); - dcaNegative.push_back(std::abs(v0.dcanegtopv())); - dcaBetweenDaughter.push_back(std::abs(v0.dcaV0daughters())); - v0Lifetime.push_back(v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * (o2::constants::physics::MassK0)); - // armenteros.push_back((v0.qtarm() / std::abs(v0.alpha()))); - - pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); - antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); - kshort = pion + antiPion; - // chargedkstar = kshort + pionbach; - kshortMother.push_back(kshort); - // chargedkstarMother.push_back(chargedkstar); - pionBachelor.push_back(pionbach); - pionBachelorIndex.push_back(track1ID); - pionBachelorSign.push_back(track1sign); - pionBachelorTPC.push_back(track1nsigTPC); - pionBachelorTOF.push_back(track1nsigTOF); - pionBachelorTOFHit.push_back(track1TOFHit); - histos.fill(HIST("hKShortMass"), kshort.M()); - } - numbV0 = numbV0 + 1; + pionBachelor.push_back(pionbach); + pionBachelorIndex.push_back(track1ID); + // pionBachelorSign.push_back(track1sign); + pionBachelorTPC.push_back(track1nsigTPC); + pionBachelorTOF.push_back(track1nsigTOF); + pionBachelorTOFHit.push_back(track1TOFHit); + } + for (const auto& v0 : V0s) { + histos.fill(HIST("hV0Info"), 0.5); + auto [kshortTag, isValid] = getK0sTags(v0, collision); + if (kshortTag && isValid) { + histos.fill(HIST("hV0Info"), 1.5); + auto postrack1 = v0.template posTrack_as(); + auto negtrack1 = v0.template negTrack_as(); + positiveIndex.push_back(postrack1.globalIndex()); + negativeIndex.push_back(negtrack1.globalIndex()); + v0Cospa.push_back(v0.v0cosPA()); + v0Radius.push_back(v0.v0radius()); + dcaPositive.push_back(std::abs(v0.dcapostopv())); + dcaNegative.push_back(std::abs(v0.dcanegtopv())); + dcaBetweenDaughter.push_back(std::abs(v0.dcaV0daughters())); + v0Lifetime.push_back(v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * (o2::constants::physics::MassK0)); + // armenteros.push_back((v0.qtarm() / std::abs(v0.alpha()))); + + pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); + antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); + kshort = pion + antiPion; + // chargedkstar = kshort + pionbach; + kshortMother.push_back(kshort); + // chargedkstarMother.push_back(chargedkstar); + histos.fill(HIST("hKShortMass"), kshort.M()); } + numbV0 = numbV0 + 1; } if (numbV0 > 1 && v0Cospa.size() > 1) { histos.fill(HIST("hEvtSelInfo"), 3.5); - kshortpionEvent(centrality, collision.index(), psiFT0C, psiFT0A, psiTPC); + kshortpionEvent(centrality, vz, collision.index(), psiFT0C, psiFT0A, psiTPC); auto indexEvent = kshortpionEvent.lastIndex(); //// Fill track table for Charged KStar////////////////// for (auto icks = kshortMother.begin(); icks != kshortMother.end(); ++icks) { auto iter = std::distance(kshortMother.begin(), icks); kshortDummy = kshortMother.at(iter); // chargedkstarDummy = chargedkstarMother.at(iter); - pionDummy = pionBachelor.at(iter); - kshortpionPair(indexEvent, v0Cospa.at(iter), v0Radius.at(iter), dcaPositive.at(iter), dcaNegative.at(iter), dcaBetweenDaughter.at(iter), v0Lifetime.at(iter), kshortDummy.Px(), kshortDummy.Py(), kshortDummy.Pz(), kshortDummy.M(), pionDummy.Px(), pionDummy.Py(), pionDummy.Pz(), pionBachelorSign.at(iter), pionBachelorTPC.at(iter), pionBachelorTOFHit.at(iter), pionBachelorTOF.at(iter), pionBachelorIndex.at(iter), positiveIndex.at(iter), negativeIndex.at(iter)); + kshortTrack(indexEvent, v0Cospa.at(iter), v0Radius.at(iter), dcaPositive.at(iter), dcaNegative.at(iter), dcaBetweenDaughter.at(iter), v0Lifetime.at(iter), kshortDummy.Px(), kshortDummy.Py(), kshortDummy.Pz(), kshortDummy.M(), positiveIndex.at(iter), negativeIndex.at(iter)); + } + for (auto ipi = pionBachelor.begin(); ipi != pionBachelor.end(); ++ipi) { + auto iterpi = std::distance(pionBachelor.begin(), ipi); + pionDummy = pionBachelor.at(iterpi); + + pionTrack(indexEvent, pionDummy.Px(), pionDummy.Py(), pionDummy.Pz(), pionBachelorTPC.at(iterpi), pionBachelorTOFHit.at(iterpi), pionBachelorTOF.at(iterpi), pionBachelorIndex.at(iterpi)); } } } diff --git a/PWGLF/Tasks/Resonances/CMakeLists.txt b/PWGLF/Tasks/Resonances/CMakeLists.txt index a1fea7646a2..682e70f828c 100644 --- a/PWGLF/Tasks/Resonances/CMakeLists.txt +++ b/PWGLF/Tasks/Resonances/CMakeLists.txt @@ -19,6 +19,11 @@ o2physics_add_dpl_workflow(phianalysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(cksspinalignder + SOURCES cksspinalignder.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(k892analysis SOURCES k892analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -237,4 +242,4 @@ o2physics_add_dpl_workflow(kstar-in-oo o2physics_add_dpl_workflow(phioo SOURCES phiOO.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/Resonances/cksspinalignder.cxx b/PWGLF/Tasks/Resonances/cksspinalignder.cxx new file mode 100644 index 00000000000..ae29ab6a6fc --- /dev/null +++ b/PWGLF/Tasks/Resonances/cksspinalignder.cxx @@ -0,0 +1,279 @@ +// 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 cksspinalignder.cxx +/// \brief Analysis task for ChargedKStar spin alignment +/// +/// \author prottay.das@cern.ch + +#include "PWGLF/DataModel/LFCKSSpinalignmentTables.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/BinningPolicy.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include + +#include +#include +#include +#include + +#include + +#include // for std::fabs +#include +// #include +#include +#include // <<< CHANGED: for dedup sets +#include +#include +#include +#include // <<< CHANGED: for seenMap +#include +#include + +// o2 includes. +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct cksspinalignder { + + struct : ConfigurableGroup { + Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + } cfgCcdbParam; + + // event sel///////// + Configurable centMin{"centMin", 0, "Minimum Centrality"}; + Configurable centMax{"centMax", 80, "Maximum Centrality"}; + // V0 selection //////////// + Configurable cosPA{"cosPA", 0.995, "Cosine Pointing Angle"}; + Configurable radiusMin{"radiusMin", 1.2, "Minimum V0 radius"}; + Configurable radiusMax{"radiusMax", 100, "Maximum V0 radius"}; + Configurable dcaPion{"dcaPion", 0.1, "DCA Pion"}; + Configurable dcaDaughters{"dcaDaughters", 1.0, "DCA between daughters"}; + Configurable lifetimeMax{"lifetimeMax", 20, "Maximum V0 lifetime"}; + Configurable ptMin{"ptMin", 0.5, "V0 Pt minimum"}; + Configurable ptMax{"ptMax", 10.0, "V0 Pt maximum"}; + Configurable v0eta{"v0eta", 0.8, "Eta cut on lambda"}; + // pion sel///////// + Configurable nsigmaCutTPC{"nsigmaCutTPC", 3.0, "N sigma TPC cut for bachelor pions"}; + Configurable nsigmaCutTOF{"nsigmaCutTOF", 3.0, "N sigma TOF cut for bachelor pions"}; + Configurable usePID{"usePID", false, "Flag for using PID selection"}; + + // Event Mixing + Configurable nEvtMixing{"nEvtMixing", 5, "Number of events to mix"}; + ConfigurableAxis cfgVtxBins{"cfgVtxBins", {10, -10, 10}, "Mixing bins - z-vertex"}; + ConfigurableAxis cfgMultBins{"cfgMultBins", {8, 0.0, 80}, "Mixing bins - centrality"}; + + // THnsparse bining + ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {50, 1.09, 1.14}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisPt{"configThnAxisPt", {100, 0.0, 10.0}, "#it{p}_{T}"}; + ConfigurableAxis configThnAxisSA{"configThnAxisSA", {20, -1.0, 1.0}, "cos#it{#theta *}"}; + ConfigurableAxis configThnAxisCentrality{"configThnAxisCentrality", {8, 0.0, 80.0}, "Centrality"}; + + // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + + histos.add("hCentrality", "Centrality distribution", kTH1F, {{80, 0, 80}}); + histos.add("hKShortMass", "hKShortMass", kTH1F, {{100, 0.45, 0.55}}); + + histos.add("hSparsesame", "hSparsesame", kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisSA, configThnAxisCentrality}); + histos.add("hSparsemix", "hSparsemix", kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisSA, configThnAxisCentrality}); + + ccdb->setURL(cfgCcdbParam.cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } + + template + bool selectionV0(T const& candidate) + { + auto kshortPt = std::sqrt(candidate.kShortPx() * candidate.kShortPx() + candidate.kShortPy() * candidate.kShortPy()); + auto px = candidate.kShortPx(); + auto py = candidate.kShortPy(); + auto pz = candidate.kShortPz(); + auto p = std::sqrt(px * px + py * py + pz * pz); + auto kshortEta = 0.5 * std::log((p + pz) / (p - pz)); + + if (std::abs(kshortEta) > v0eta) { + return false; + } + if (candidate.v0Cospa() < cosPA) { + return false; + } + if (candidate.v0Radius() > radiusMax) { + return false; + } + if (candidate.v0Radius() < radiusMin) { + return false; + } + if (candidate.dcaBetweenDaughter() > dcaDaughters) { + return false; + } + if (std::abs(candidate.dcaPositive()) < dcaPion && std::abs(candidate.dcaNegative()) < dcaPion) { + return false; + } + if (candidate.v0Lifetime() > lifetimeMax) { + return false; + } + if (kshortPt < ptMin) { + return false; + } + if (kshortPt > ptMax) { + return false; + } + return true; + } + + template + bool selectionPID(const T& candidate) + { + auto px = candidate.pionBachPx(); + auto py = candidate.pionBachPy(); + auto pz = candidate.pionBachPz(); + auto p = std::sqrt(px * px + py * py + pz * pz); + float lowmom = 0.5; + if (p < lowmom) { + if (!candidate.pionBachTOFHit() && std::abs(candidate.pionBachTPC()) < nsigmaCutTPC) { + return true; + } else if (candidate.pionBachTOFHit() && std::sqrt(candidate.pionBachTPC() * candidate.pionBachTPC() + candidate.pionBachTOF() * candidate.pionBachTOF()) < nsigmaCutTOF) { + return true; + } + } else if (candidate.pionBachTOFHit() && std::sqrt(candidate.pionBachTPC() * candidate.pionBachTPC() + candidate.pionBachTOF() * candidate.pionBachTOF()) < nsigmaCutTOF) { + return true; + } + return false; + } + + std::tuple computePtEtaPhi(float px, float py, float pz) + { + float pt = std::sqrt(px * px + py * py); + float p = std::sqrt(px * px + py * py + pz * pz); + float eta = (p != std::abs(pz)) ? 0.5 * std::log((p + pz) / (p - pz)) : 0.0f; // avoid division by zero + float phi = RecoDecay::constrainAngle(std::atan2(py, px)); + return {pt, eta, phi}; + } + + ROOT::Math::PtEtaPhiMVector kshort, pion, chkstar; + ROOT::Math::PtEtaPhiMVector kshortmix, pionmix, chkstarmix; + ROOT::Math::PxPyPzMVector fourVecDauCM, fourVecDauCMmix; + ROOT::Math::XYZVector threeVecDauCM, eventplaneVecNorm, threeVecDauCMmix, eventplaneVecNormmix; + + Filter centralityFilter = (nabs(aod::kshortpionevent::cent) < centMax && nabs(aod::kshortpionevent::cent) > centMin); + + using EventCandidates = soa::Filtered; + + void processSameData(EventCandidates::iterator const& collision, aod::KShortTracks const& V0s, aod::PionTracks const& piontracks) + { + auto centrality = collision.cent(); + histos.fill(HIST("hCentrality"), centrality); + + auto psiFT0C = collision.psiFT0C(); + + for (const auto& v0 : V0s) { + if (!selectionV0(v0)) { + continue; + } + auto [kshortPt, kshortEta, kshortPhi] = computePtEtaPhi(v0.kShortPx(), v0.kShortPy(), v0.kShortPz()); + kshort = ROOT::Math::PtEtaPhiMVector(kshortPt, kshortEta, kshortPhi, v0.kShortMass()); + histos.fill(HIST("hKShortMass"), kshort.M()); + + for (const auto& piontrack : piontracks) { + auto [pionPt, pionEta, pionPhi] = computePtEtaPhi(piontrack.pionBachPx(), piontrack.pionBachPy(), piontrack.pionBachPz()); + pion = ROOT::Math::PtEtaPhiMVector(pionPt, pionEta, pionPhi, o2::constants::physics::MassPionCharged); + + if (piontrack.pionBachIndex() == v0.pionIndex1() || piontrack.pionBachIndex() == v0.pionIndex2()) + continue; // checking if bachelor pion is khort daughter or not -> skip further processing if such is the case + + if (usePID && !selectionPID(piontrack)) + continue; // checking PID + + chkstar = kshort + pion; + + ROOT::Math::Boost boost{chkstar.BoostToCM()}; + fourVecDauCM = boost(kshort); + threeVecDauCM = fourVecDauCM.Vect(); + eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); + auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); + + histos.fill(HIST("hSparsesame"), chkstar.M(), chkstar.Pt(), cosThetaStar, centrality); + } + } + } + PROCESS_SWITCH(cksspinalignder, processSameData, "Process same data", true); + + // Processing Event Mixing + SliceCache cache; + using BinningType = ColumnBinningPolicy; + BinningType colBinning{{cfgVtxBins, cfgMultBins}, true}; + Preslice tracksPerCollisionV0 = aod::kshortpionpair::kshortpioneventId; + Preslice tracksPerCollisionBach = aod::kshortpionpair::kshortpioneventId; + + void processMixedData(EventCandidates const& collisions, aod::KShortTracks const& V0s, aod::PionTracks const& piontracks) + { + for (const auto& [collision1, collision2] : selfCombinations(colBinning, nEvtMixing, -1, collisions, collisions)) { + if (collision1.index() == collision2.index()) { + continue; + } + auto centrality = collision1.cent(); + auto psiFT0Cmix = collision1.psiFT0C(); + + auto groupV0 = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + auto groupPion = piontracks.sliceBy(tracksPerCollisionBach, collision2.index()); + for (const auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV0, groupPion))) { + if (!selectionV0(t1)) + continue; + auto [kshortPtmix, kshortEtamix, kshortPhimix] = computePtEtaPhi(t1.kShortPx(), t1.kShortPy(), t1.kShortPz()); + kshortmix = ROOT::Math::PtEtaPhiMVector(kshortPtmix, kshortEtamix, kshortPhimix, t1.kShortMass()); + + auto [pionPtmix, pionEtamix, pionPhimix] = computePtEtaPhi(t2.pionBachPx(), t2.pionBachPy(), t2.pionBachPz()); + if (usePID && !selectionPID(t2)) + continue; // checking PID + pionmix = ROOT::Math::PtEtaPhiMVector(pionPtmix, pionEtamix, pionPhimix, o2::constants::physics::MassPionCharged); + + chkstarmix = kshortmix + pionmix; + + ROOT::Math::Boost boost{chkstarmix.BoostToCM()}; + fourVecDauCMmix = boost(kshortmix); + threeVecDauCMmix = fourVecDauCMmix.Vect(); + eventplaneVecNormmix = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0Cmix), -std::cos(2.0 * psiFT0Cmix), 0); + auto cosThetaStarmix = eventplaneVecNormmix.Dot(threeVecDauCMmix) / std::sqrt(threeVecDauCMmix.Mag2()) / std::sqrt(eventplaneVecNormmix.Mag2()); + + histos.fill(HIST("hSparsemix"), chkstarmix.M(), chkstarmix.Pt(), cosThetaStarmix, centrality); + } + } + } + PROCESS_SWITCH(cksspinalignder, processMixedData, "Process mixed data", true); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +}