From 557052e4a2e625060f2d4776758e7ca4cd9e5948 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Mon, 26 Oct 2026 13:03:16 +0100 Subject: [PATCH 1/4] Adjusments in the Tracking Translator to the updated actso2 output --- ALICE3/DataModel/tracksAlice3.h | 37 ++++++- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 2 +- .../alice3TrackingTranslator.cxx | 104 +++++++++++------- 3 files changed, 100 insertions(+), 43 deletions(-) diff --git a/ALICE3/DataModel/tracksAlice3.h b/ALICE3/DataModel/tracksAlice3.h index 327d0587b64..d398267a54b 100644 --- a/ALICE3/DataModel/tracksAlice3.h +++ b/ALICE3/DataModel/tracksAlice3.h @@ -26,6 +26,7 @@ namespace o2::aod { namespace track_alice3 { +<<<<<<< Updated upstream DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, bool); //! is reconstructed or not DECLARE_SOA_COLUMN(NSiliconHits, nSiliconHits, int); //! number of silicon hits DECLARE_SOA_COLUMN(NTPCHits, nTPCHits, int); //! number of tpc hits @@ -34,6 +35,19 @@ DECLARE_SOA_COLUMN(TrackType, trackType, int); //! Type of the trac DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! Has track contributed to the PV fit? DECLARE_SOA_COLUMN(TrackIU, trackIU, float); //! Innermost update: radius (cm) of the innermost hit assigned to the track DECLARE_SOA_COLUMN(TrackOU, trackOU, float); //! Outermost update: radius (cm) of the outermost hit assigned to the track +======= +DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, bool); //! is reconstructed or not +DECLARE_SOA_COLUMN(NSiliconHits, nSiliconHits, int); //! number of silicon hits +DECLARE_SOA_COLUMN(NTPCHits, nTPCHits, int); //! number of tpc hits +DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); //! PDG code of the linked truth MC particle +DECLARE_SOA_COLUMN(TrackType, trackType, int); //! Type of the track +DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! Has track contributed to the PV fit? +DECLARE_SOA_COLUMN(SecondaryVertexRadius, secondaryVertexRadius, float); //! Radius of the secondary vertex associated with the track +DECLARE_SOA_COLUMN(SecondaryVertexX, secondaryVertexX, float); //! X position of the secondary vertex associated with the track +DECLARE_SOA_COLUMN(SecondaryVertexY, secondaryVertexY, float); //! Y position of the secondary vertex associated with the track +DECLARE_SOA_COLUMN(SecondaryVertexZ, secondaryVertexZ, float); //! Z position of the secondary vertex associated with the track + +>>>>>>> Stashed changes } // namespace track_alice3 DECLARE_SOA_TABLE(TracksAlice3, "AOD", "TRACKSALICE3", track_alice3::IsReconstructed, @@ -45,23 +59,40 @@ DECLARE_SOA_TABLE(TracksAlice3Pdg, "AOD", "TRACKSALICE3PDG", track_alice3::PdgCode); using TrackAlice3Pdg = TracksAlice3Pdg::iterator; -DECLARE_SOA_TABLE(TracksExtraA3, "AOD", "TracksExtraA3", +DECLARE_SOA_TABLE(TracksExtraA3_000, "AOD", "TracksExtraA3", track_alice3::NSiliconHits, track_alice3::NTPCHits, track_alice3::TrackType, track_alice3::IsPVContributor); +DECLARE_SOA_TABLE_VERSIONED(TracksExtraA3_001, "AOD", "TracksExtraA3", 1, + track_alice3::NSiliconHits, + track_alice3::NTPCHits, + track_alice3::TrackType, + track_alice3::IsPVContributor, + track_alice3::SecondaryVertexRadius, + track_alice3::SecondaryVertexX, + track_alice3::SecondaryVertexY, + track_alice3::SecondaryVertexZ); +using TracksExtraA3 = TracksExtraA3_001; using TrackExtraA3 = TracksExtraA3::iterator; - namespace mcparticle_alice3 { +<<<<<<< Updated upstream DECLARE_SOA_COLUMN(NHits, nHits, int); //! number of silicon hits DECLARE_SOA_COLUMN(Charge, charge, float); //! particle charge DECLARE_SOA_COLUMN(DecayRadius, decayRadius, float); //! Radius for decayed particle produced by decayer (-1 if not decayed) DECLARE_SOA_BITMAP_COLUMN(DecayerBits, decayerBits, 8); //! Bit mask for particle produced by the OTF decayer +======= +DECLARE_SOA_COLUMN(NHits, nHits, int); //! number of silicon hits +DECLARE_SOA_COLUMN(Charge, charge, float); //! particle charge +DECLARE_SOA_BITMAP_COLUMN(DecayerBits, decayerBits, 8); //! Bit mask for particle produced by the OTF decayer +DECLARE_SOA_COLUMN(SecondaryVertexRadius, secondaryVertexRadius, float); //! Radius of the secondary vertex associated with the track +>>>>>>> Stashed changes } // namespace mcparticle_alice3 DECLARE_SOA_TABLE(MCParticlesExtraA3, "AOD", "MCParticlesExtraA3", mcparticle_alice3::NHits, - mcparticle_alice3::Charge); + mcparticle_alice3::Charge, + mcparticle_alice3::SecondaryVertexRadius); using MCParticleExtraA3 = MCParticlesExtraA3::iterator; DECLARE_SOA_TABLE(OTFParticleExtras, "AOD", "OTFPARTICLEEXTRA", diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 7e84ec9c223..f0299537531 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -1817,7 +1817,7 @@ struct OnTheFlyTracker { trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), trackParCov.getSigma1Pt2()); tableMcTrackLabels(trackParCov.mcLabel, 0); - tableTracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits, trackParCov.trackType, trackParCov.isPVContributor); + tableTracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits, trackParCov.trackType, trackParCov.isPVContributor, -1, -1, -1, -1); // populate extra tables if required to do so if (populateTracksExtra) { diff --git a/ALICE3/TableProducer/alice3TrackingTranslator.cxx b/ALICE3/TableProducer/alice3TrackingTranslator.cxx index e0e742fc9d0..ffb0a77cab5 100644 --- a/ALICE3/TableProducer/alice3TrackingTranslator.cxx +++ b/ALICE3/TableProducer/alice3TrackingTranslator.cxx @@ -239,7 +239,7 @@ struct Alice3TrackingTranslator { SETADDRESS("ePY_fit", m_ePY_fit); SETADDRESS("ePZ_fit", m_ePZ_fit); SETADDRESS("cov_eX_eX", m_cov_eX_eX); - // SETADDRESS("cov_eY_eY", m_cov_eY_eY); + SETADDRESS("cov_eY_eY", m_cov_eY_eY); SETADDRESS("cov_eZ_eZ", m_cov_eZ_eZ); SETADDRESS("cov_ePX_ePX", m_cov_ePX_ePX); SETADDRESS("cov_ePY_ePY", m_cov_ePY_ePY); @@ -278,8 +278,8 @@ struct Alice3TrackingTranslator { std::vector* m_ePZ_fit = nullptr; // global momentum pz // covariance matrices for fitted track parameters (if available) - std::vector* m_cov_eX_eX = nullptr; // covariance of global position x - // std::vector* m_cov_eY_eY = nullptr; // covariance of global position y + std::vector* m_cov_eX_eX = nullptr; // covariance of global position x + std::vector* m_cov_eY_eY = nullptr; // covariance of global position y std::vector* m_cov_eZ_eZ = nullptr; // covariance of global position z std::vector* m_cov_ePX_ePX = nullptr; // covariance of global momentum px std::vector* m_cov_ePY_ePY = nullptr; // covariance of global momentum py @@ -326,7 +326,7 @@ struct Alice3TrackingTranslator { } std::vector* barcode = nullptr; }; - void addMCParticle(int collIndex, ParticleStruct& fileParticles, int iParticle, uint8_t flags, int firstMother, int firstDaughter, int secondDaughter, int numberOfHits) + void addMCParticle(int collIndex, ParticleStruct& fileParticles, int iParticle, uint8_t flags, int firstMother, int firstDaughter, int secondDaughter, int numberOfHits, float secondaryVertexRadius) { int mothers[2] = {firstMother, firstMother}; int daughters[2] = {firstDaughter, secondDaughter}; @@ -341,12 +341,13 @@ struct Alice3TrackingTranslator { fileParticles.m_py->at(iParticle), // m_py fileParticles.m_pz->at(iParticle), // m_pz std::hypot(fileParticles.m_p->at(iParticle), fileParticles.m_m->at(iParticle)), // e - fileParticles.m_vx->at(iParticle), // m_vx - fileParticles.m_vy->at(iParticle), // m_vy - fileParticles.m_vz->at(iParticle), // m_vz - fileParticles.m_vt->at(iParticle)); // m_vt + fileParticles.m_vx->at(iParticle) * 0.1, // m_vx + fileParticles.m_vy->at(iParticle) * 0.1, // m_vy + fileParticles.m_vz->at(iParticle) * 0.1, // m_vz + fileParticles.m_vt->at(iParticle) * 0.1); // m_vt tableMCParticlesExtraA3(numberOfHits, // number_of_hits - fileParticles.m_q->at(iParticle)); // charge + fileParticles.m_q->at(iParticle), // charge + secondaryVertexRadius); // secondary_vertex_radius }; void process(o2::aod::BCs const&) @@ -426,11 +427,13 @@ struct Alice3TrackingTranslator { // barcode -> global AO2D index (used later for track labels) std::map barcodeToGlobalIdx; - std::map> barcodeToVertexPosition; + std::map> globalToVertexPosition; std::map GlobalIdxToMotherIdx; + std::map GlobalIdxSecVertexRadiusIncoming; std::map GlobalIdxToPDGCode; std::map GlobalToLocalIdx; std::map> GlobalIdxToDaughterIdxs; + for (size_t iPart = 0; iPart < nParticlesSim; ++iPart) { Key key = keyOf( fileParticlesSim.m_vertex_primary->at(iPart), @@ -465,6 +468,7 @@ struct Alice3TrackingTranslator { auto iteratorMother = barcodeToGlobalIdx.find(kd); if (iteratorMother != barcodeToGlobalIdx.end()) { int motherIdx = iteratorMother->second; + GlobalIdxSecVertexRadiusIncoming[motherIdx] = std::hypot(fileVertices.m_x->at(j) * 0.1, fileVertices.m_y->at(j) * 0.1); for (size_t d2 = 0; d2 < (*fileVertices.m_outgoing_particles_vertex_secondary)[j].size(); ++d2) { Key kd2 = keyOf( (*fileVertices.m_outgoing_particles_vertex_primary)[j][d2], @@ -472,12 +476,12 @@ struct Alice3TrackingTranslator { (*fileVertices.m_outgoing_particles_particle)[j][d2], (*fileVertices.m_outgoing_particles_generation)[j][d2], (*fileVertices.m_outgoing_particles_sub_particle)[j][d2]); - barcodeToVertexPosition[kd2].push_back(fileVertices.m_x->at(j)); - barcodeToVertexPosition[kd2].push_back(fileVertices.m_y->at(j)); - barcodeToVertexPosition[kd2].push_back(fileVertices.m_z->at(j)); auto iteratorDaughter = barcodeToGlobalIdx.find(kd2); if (iteratorDaughter != barcodeToGlobalIdx.end()) { int daughterIdx = iteratorDaughter->second; + globalToVertexPosition[daughterIdx].push_back(fileVertices.m_x->at(j)); + globalToVertexPosition[daughterIdx].push_back(fileVertices.m_y->at(j)); + globalToVertexPosition[daughterIdx].push_back(fileVertices.m_z->at(j)); GlobalIdxToMotherIdx[daughterIdx] = motherIdx; GlobalIdxToDaughterIdxs[motherIdx].push_back(daughterIdx); } @@ -486,7 +490,8 @@ struct Alice3TrackingTranslator { } } for (size_t iPart = 0; iPart < nParticlesSim; ++iPart) { - int globalIdx = firstIdxThisEvent + static_cast(iPart); + float secondaryVertexRadius = -1.0f; + int globalIdx = firstIdxThisEvent + (int)iPart; int motherIdx = -1; if (GlobalIdxToMotherIdx.find(globalIdx) != GlobalIdxToMotherIdx.end()) { motherIdx = GlobalIdxToMotherIdx[globalIdx]; @@ -501,6 +506,13 @@ struct Alice3TrackingTranslator { if (daughters.size() > 1) { secondDaughter = daughters[1]; } + if (globalToVertexPosition.find(globalIdx) != globalToVertexPosition.end()) { + const auto& vertexPos = globalToVertexPosition[globalIdx]; + secondaryVertexRadius = std::hypot(vertexPos[0] * 0.1, vertexPos[1] * 0.1); + } + if (secondaryVertexRadius == -1) { + secondaryVertexRadius = GlobalIdxSecVertexRadiusIncoming[globalIdx]; + } } // Determine flags for the MC particle // TODO: For now primary are only those without mother, but all based on PhysicalPrimary definition should be considered. @@ -513,24 +525,24 @@ struct Alice3TrackingTranslator { } GlobalIdxToPDGCode[globalIdx] = fileParticlesSim.m_particle_type->at(iPart); GlobalToLocalIdx[globalIdx] = iPart; - addMCParticle(tableMcCollisions.lastIndex(), fileParticlesSim, iPart, flags, motherIdx, firstDaughter, secondDaughter, fileParticlesSim.m_number_of_hits->at(iPart)); + addMCParticle(tableMcCollisions.lastIndex(), fileParticlesSim, iPart, flags, motherIdx, firstDaughter, secondDaughter, fileParticlesSim.m_number_of_hits->at(iPart), secondaryVertexRadius); } - - tableCollisions(0, // bcId - collisionX, // posX - collisionY, // posY - collisionZ, // posZ - 0.0f, // covXX - 0.0f, // covXY - 0.0f, // covXZ - 0.0f, // covYY - 0.0f, // covYZ - 0.0f, // covZZ - 0, // flags - 0.0f, // m_chi2Sum - 0, // numContrib - 0.0f, // collisionTime - 0.0f); // collisionTimeRes + const float scale = 0.1f; + tableCollisions(0, // bcId + collisionX * scale, // posX + collisionY * scale, // posY + collisionZ * scale, // posZ + 0.0f, // covXX + 0.0f, // covXY + 0.0f, // covXZ + 0.0f, // covYY + 0.0f, // covYZ + 0.0f, // covZZ + 0, // flags + 0.0f, // m_chi2Sum + 0, // numContrib + 0.0f, // collisionTime + 0.0f); // collisionTimeRes tableMcCollisionLabels(iEvent, // mcCollisionId 0); // mcMask @@ -585,7 +597,7 @@ struct Alice3TrackingTranslator { // Fill covariance matrices float cxx = fileTracksummary.m_cov_eX_eX->at(iTrack); - float cyy = cxx; // fileTracksummary.cov_eY_eY->at(iTrack); + float cyy = fileTracksummary.m_cov_eY_eY->at(iTrack); float czz = fileTracksummary.m_cov_eZ_eZ->at(iTrack); float cxy = fileTracksummary.m_cov_eX_eY->at(iTrack); float cxz = fileTracksummary.m_cov_eX_eZ->at(iTrack); @@ -606,7 +618,8 @@ struct Alice3TrackingTranslator { float czpy = fileTracksummary.m_cov_eZ_ePY->at(iTrack); float czpz = fileTracksummary.m_cov_eZ_ePZ->at(iTrack); // Create TrackParCov object with covariance matrix - std::array position = {x, y, z}; + + std::array position = {x * scale, y * scale, z * scale}; std::array momentum = {px, py, pz}; std::array trackCov = {cxx, cxy, cyy, cxz, cyz, czz, cxpx, cypx, czpx, cpxpx, cxpy, cypy, czpy, cpxpy, cpypy, cxpz, cypz, czpz, cpxpz, cpypz, cpzpz}; o2::track::TrackParCov trackParCov(position, momentum, trackCov, charge); @@ -669,15 +682,28 @@ struct Alice3TrackingTranslator { tableTracksAlice3(true, // isReconstructed -1.f, // todo: track innermost update -1.f); // todo: track outermost update - if (mcParticleIdx > 0) + if (mcParticleIdx > 0) { tableTracksAlice3Pdg(GlobalIdxToPDGCode[mcParticleIdx]); // PdgCode to the linked MC truth particle - else + } else { tableTracksAlice3Pdg(0); // No linked MC truth particle + } - tableTracksExtraA3(m_nMeasurements, // nSiliconHits (using m_nMeasurements as proxy) - 0, // nTPCHits - 0, // trackType - false); // isPVContributor + float secondaryVertexRadius = 0; + std::array vertexPos = {0.0, 0.0, 0.0}; + if (mcParticleIdx > 0) { + vertexPos[0] = fileParticlesSim.m_vx->at(GlobalToLocalIdx[mcParticleIdx]) * 0.1; + vertexPos[1] = fileParticlesSim.m_vy->at(GlobalToLocalIdx[mcParticleIdx]) * 0.1; + vertexPos[2] = fileParticlesSim.m_vz->at(GlobalToLocalIdx[mcParticleIdx]) * 0.1; + secondaryVertexRadius = std::hypot(vertexPos[0], vertexPos[1]); + } + tableTracksExtraA3(m_nMeasurements, // nSiliconHits (using m_nMeasurements as proxy) + 0, // nTPCHits + 0, // trackType + false, // isPVContributor + secondaryVertexRadius, // secondaryVertexRadius + vertexPos[0], + vertexPos[1], + vertexPos[2]); // Fill extra track info tableStoredTracksExtra(0.f, // TPCInnerParam static_cast(0), // Flags From 281f0b968e00b9c7509629c7a990fbdd8bc29832 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Wed, 28 Oct 2026 12:50:58 +0100 Subject: [PATCH 2/4] fix the tracksAlice3.h --- ALICE3/DataModel/tracksAlice3.h | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/ALICE3/DataModel/tracksAlice3.h b/ALICE3/DataModel/tracksAlice3.h index d398267a54b..37c53e6e38d 100644 --- a/ALICE3/DataModel/tracksAlice3.h +++ b/ALICE3/DataModel/tracksAlice3.h @@ -26,7 +26,7 @@ namespace o2::aod { namespace track_alice3 { -<<<<<<< Updated upstream + DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, bool); //! is reconstructed or not DECLARE_SOA_COLUMN(NSiliconHits, nSiliconHits, int); //! number of silicon hits DECLARE_SOA_COLUMN(NTPCHits, nTPCHits, int); //! number of tpc hits @@ -35,19 +35,11 @@ DECLARE_SOA_COLUMN(TrackType, trackType, int); //! Type of the trac DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! Has track contributed to the PV fit? DECLARE_SOA_COLUMN(TrackIU, trackIU, float); //! Innermost update: radius (cm) of the innermost hit assigned to the track DECLARE_SOA_COLUMN(TrackOU, trackOU, float); //! Outermost update: radius (cm) of the outermost hit assigned to the track -======= -DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, bool); //! is reconstructed or not -DECLARE_SOA_COLUMN(NSiliconHits, nSiliconHits, int); //! number of silicon hits -DECLARE_SOA_COLUMN(NTPCHits, nTPCHits, int); //! number of tpc hits -DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); //! PDG code of the linked truth MC particle -DECLARE_SOA_COLUMN(TrackType, trackType, int); //! Type of the track -DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! Has track contributed to the PV fit? DECLARE_SOA_COLUMN(SecondaryVertexRadius, secondaryVertexRadius, float); //! Radius of the secondary vertex associated with the track DECLARE_SOA_COLUMN(SecondaryVertexX, secondaryVertexX, float); //! X position of the secondary vertex associated with the track DECLARE_SOA_COLUMN(SecondaryVertexY, secondaryVertexY, float); //! Y position of the secondary vertex associated with the track DECLARE_SOA_COLUMN(SecondaryVertexZ, secondaryVertexZ, float); //! Z position of the secondary vertex associated with the track ->>>>>>> Stashed changes } // namespace track_alice3 DECLARE_SOA_TABLE(TracksAlice3, "AOD", "TRACKSALICE3", track_alice3::IsReconstructed, @@ -77,17 +69,12 @@ using TracksExtraA3 = TracksExtraA3_001; using TrackExtraA3 = TracksExtraA3::iterator; namespace mcparticle_alice3 { -<<<<<<< Updated upstream + DECLARE_SOA_COLUMN(NHits, nHits, int); //! number of silicon hits DECLARE_SOA_COLUMN(Charge, charge, float); //! particle charge DECLARE_SOA_COLUMN(DecayRadius, decayRadius, float); //! Radius for decayed particle produced by decayer (-1 if not decayed) DECLARE_SOA_BITMAP_COLUMN(DecayerBits, decayerBits, 8); //! Bit mask for particle produced by the OTF decayer -======= -DECLARE_SOA_COLUMN(NHits, nHits, int); //! number of silicon hits -DECLARE_SOA_COLUMN(Charge, charge, float); //! particle charge -DECLARE_SOA_BITMAP_COLUMN(DecayerBits, decayerBits, 8); //! Bit mask for particle produced by the OTF decayer DECLARE_SOA_COLUMN(SecondaryVertexRadius, secondaryVertexRadius, float); //! Radius of the secondary vertex associated with the track ->>>>>>> Stashed changes } // namespace mcparticle_alice3 DECLARE_SOA_TABLE(MCParticlesExtraA3, "AOD", "MCParticlesExtraA3", mcparticle_alice3::NHits, From 93e12ab4a026a37391a5bd13884eca4d103546ac Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Wed, 28 Oct 2026 15:06:27 +0100 Subject: [PATCH 3/4] new process function for daughter efficiency, new QA histograms, adjusted MC association for ACTS part --- .../TableProducer/alice3strangenessFinder.cxx | 308 ++++++++++++++---- 1 file changed, 236 insertions(+), 72 deletions(-) diff --git a/ALICE3/TableProducer/alice3strangenessFinder.cxx b/ALICE3/TableProducer/alice3strangenessFinder.cxx index 8d8216c4c5d..baf4a0be259 100644 --- a/ALICE3/TableProducer/alice3strangenessFinder.cxx +++ b/ALICE3/TableProducer/alice3strangenessFinder.cxx @@ -64,7 +64,7 @@ using namespace o2::framework; using namespace o2::constants::physics; using Alice3TracksWPid = soa::Join; -using Alice3TracksACTS = soa::Join; +using Alice3TracksACTS = soa::Join; using Alice3TracksOTF = soa::Join; using Alice3MCParticles = soa::Join; @@ -90,7 +90,7 @@ struct Alice3strangenessFinder { ConfigurableAxis axisDCA{"axisDCA", {200, 0, 200}, "DCA axis"}; ConfigurableAxis axisEta{"axisEta", {80, -4.f, 4.f}, "Eta axis"}; - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.025f, 0.05f, 0.075f, 0.1f, 0.125f, 0.15f, 0.175f, 0.2f, 0.225f, 0.25f, 0.275f, 0.3f, 0.325f, 0.35f, 0.375f, 0.4f, 0.425f, 0.45f, 0.475f, 0.5f, 0.525f, 0.55f, 0.575f, 0.6f, 0.625f, 0.65f, 0.675f, 0.7f, 0.725f, 0.75f, 0.775f, 0.8f, 0.82f, 0.85f, 0.875f, 0.9f, 0.925f, 0.95f, 0.975f, 1.0f, 1.05f, 1.1f}, "pt axis for QA histograms"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.05f, 0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.5f, 0.55f, 0.6f, 0.65f, 0.7f, 0.75f, 0.8f, 0.85f, 0.9f, 0.95f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.25f, 2.5, 2.75, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f, 10.0f, 12.f, 15.f}, "pt axis for QA histograms"}; // DCA Fitter struct : ConfigurableGroup { @@ -133,11 +133,24 @@ struct Alice3strangenessFinder { Configurable cascMaxEta{"cascMaxEta", 2.5f, "DCA between cascade daughters (cm)"}; } presel; + // Daughter Track Eff calculation + struct : ConfigurableGroup { + std::string prefix = "daughEff"; + Configurable analyseK0Daughters{"analyseK0Daughters", true, ""}; + Configurable analyseLambdaDaughters{"analyseLambdaDaughters", false, ""}; + Configurable analyseAntiLambdaDaughters{"analysAntiLambdaDaughters", false, ""}; + Configurable analyseXiMinusDaughters{"analyseXiMinusDaughters", false, ""}; + Configurable analyseXiPlusDaughters{"analyseXiPlusDaughters", false, ""}; + Configurable analysOmegaMinusDaughters{"analysOmegaMinusDaughters", false, ""}; + Configurable analyseOmegaPlusDaughters{"analyseOmegaPlusDaughters", false, ""}; + } daughEff; + // Operation Configurable magneticField{"magneticField", 20.0f, "Magnetic field (in kilogauss)"}; Configurable mcSameMotherCheck{"mcSameMotherCheck", true, "check if tracks come from the same MC mother"}; // for the ACTS study + Configurable useGeneratedSVposition{"useGeneratedSVposition", false, "use the MC truth position of V0 decay"}; Configurable isK0Gun{"isK0Gun", false, "is K0s Monte Carlo gun used"}; Configurable isLambdaGun{"isLambdaGun", true, "is Lambda Monte Carlo gun used"}; Configurable skipFitter{"skipFitter", false, "calculate V0 properties without calling the DCA fitter, using only the track parameters "}; @@ -183,6 +196,8 @@ struct Alice3strangenessFinder { // decay properties float dcaDau{}; + float posDauDCAxy{}; + float negDauDCAxy{}; float eta{}; std::array p{}; std::array posSV{}; @@ -250,8 +265,18 @@ struct Alice3strangenessFinder { hV0Counter->GetXaxis()->SetBinLabel(3, "AntiLambda"); hV0Counter->GetXaxis()->SetBinLabel(4, "Misidentified"); - histos.add("hRadiusVsHitsNeg", "", kTH2D, {{400, 0, 400}, {12, 0.5, 12.5}}); // radius vs hist for MC studies - histos.add("hRadiusVsHitsPos", "", kTH2D, {{400, 0, 400}, {12, 0.5, 12.5}}); // radius vs hist for MC studies + auto hPtResolutionPositive = histos.add("hPtResolutionPositive", "hPtResolutionPositive", kTH2D, {{axisPt}, {axisPt}}); + hPtResolutionPositive->GetXaxis()->SetTitle("p_{T}^{reco} (GeV/c)"); + hPtResolutionPositive->GetYaxis()->SetTitle("p_{T}^{true} (GeV/c)"); + + auto hPtResolutionNegative = histos.add("hPtResolutionNegative", "hPtResolutionNegative", kTH2D, {{axisPt}, {axisPt}}); + hPtResolutionNegative->GetXaxis()->SetTitle("p_{T}^{reco} (GeV/c)"); + hPtResolutionNegative->GetYaxis()->SetTitle("p_{T}^{true} (GeV/c)"); + + auto hPtRes1DNegDau = histos.add("hPtRes1DNegDau", "hPtRes1DNegDau", kTH1D, {{100, -0.2, 0.2}}); + hPtRes1DNegDau->GetXaxis()->SetTitle("(p_{T}^{gen} - p_{T}^{reco})/p_{T}^{gen}"); + auto hPtRes1DPosDau = histos.add("hPtRes1DPosDau", "hPtRes1DPosDau", kTH1D, {{100, -0.2, 0.2}}); + hPtRes1DPosDau->GetXaxis()->SetTitle("(p_{T}^{gen} - p_{T}^{reco})/p_{T}^{gen}"); auto hV0Building = histos.add("hV0Building", "hV0Building", kTH1D, {{10, 0.5, 10.5}}); hV0Building->GetXaxis()->SetBinLabel(1, "Pair"); @@ -279,18 +304,42 @@ struct Alice3strangenessFinder { histos.add("CascadeBuilding/hXiMass", "", kTH1D, {axisXiMass}); histos.add("CascadeBuilding/hOmegaMass", "", kTH1D, {axisOmegaMass}); } - histos.add("hPx", "", kTH1D, {{200, -10.f, 10.f}}); - histos.add("hPy", "", kTH1D, {{200, -10.f, 10.f}}); - histos.add("hPz", "", kTH1D, {{200, -10.f, 10.f}}); - - histos.add("hPxPairs", "", kTH1D, {{200, -10.f, 10.f}}); - histos.add("hPyPairs", "", kTH1D, {{200, -10.f, 10.f}}); - histos.add("hPzPairs", "", kTH1D, {{200, -10.f, 10.f}}); - - histos.add("hPxV0CandDaughter", "", kTH1D, {{200, -10.f, 10.f}}); - histos.add("hPyV0CandDaughter", "", kTH1D, {{200, -10.f, 10.f}}); - histos.add("hPzV0CandDaughter", "", kTH1D, {{200, -10.f, 10.f}}); + histos.add("hPxPosRepropagated", "", kTH2D, {{200, -10.f, 10.f}, {200, -10.f, 10.f}}); + histos.add("hPyPosRepropagated", "", kTH2D, {{200, -10.f, 10.f}, {200, -10.f, 10.f}}); + histos.add("hPzPosRepropagated", "", kTH2D, {{200, -10.f, 10.f}, {200, -10.f, 10.f}}); + + histos.add("hPxNegRepropagated", "", kTH2D, {{200, -10.f, 10.f}, {200, -10.f, 10.f}}); + histos.add("hPyNegRepropagated", "", kTH2D, {{200, -10.f, 10.f}, {200, -10.f, 10.f}}); + histos.add("hPzNegRepropagated", "", kTH2D, {{200, -10.f, 10.f}, {200, -10.f, 10.f}}); + histos.add("hRadius", "", kTH1D, {{100, 0, 100}}); + histos.add("hRadiusGenNeg", "", kTH1D, {{100, 0, 100}}); + histos.add("hRadiusGenPos", "", kTH1D, {{100, 0, 100}}); + + histos.add("hMomentumPosRepropagated", "", kTH2D, {{500, 0.f, 15.f}, {500, -0.f, 15.f}}); + histos.add("hMomentumNegRepropagated", "", kTH2D, {{500, 0.f, 15.f}, {500, -0.f, 15.f}}); + + histos.add("hCosPhiRepropagated", "", kTH2D, {{100, 0.8f, 1.f}, {100, 0.8f, 1.f}}); + + if (doprocessDaughterTracksForEffACTS || doprocessDaughterTracksForEffOTF) { + histos.add("K0Short/hNegDaughterRecoTruePtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("K0Short/hNegDaughterRecoPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("K0Short/hPosDaughterRecoTruePtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("K0Short/hPosDaughterRecoPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.addClone("K0Short/", "Lambda"); + histos.addClone("K0Short/", "AntiLambda"); + } + if (doprocessMCTrueFromACTS) { + histos.add("K0Short/hNegDaughterGenPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("K0Short/hPosDaughterGenPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Lambda/hNegDaughterGenPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Lambda/hPosDaughterGenPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("AntiLambda/hNegDaughterGenPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + histos.add("AntiLambda/hPosDaughterGenPtEta", "", kTH2D, {{axisPt}, {axisEta}}); + + histos.add("hRadiusVsHitsNeg", "", kTH2D, {{100, 0, 100}, {12, 0.5, 12.5}}); // radius vs hist for MC studies + histos.add("hRadiusVsHitsPos", "", kTH2D, {{100, 0, 100}, {12, 0.5, 12.5}}); // radius vs hist for MC studies + } histos.print(); } @@ -343,6 +392,19 @@ struct Alice3strangenessFinder { } // end association check return returnValue; } + template + bool checkSameMotherGen(TMCParticle const& mcParticle1, TMCParticle const& mcParticle2) + { + bool returnValue = false; + if (mcParticle1.has_mothers() && mcParticle2.has_mothers()) { + auto motherIds1 = mcParticle1.mothersIds(); + auto motherIds2 = mcParticle2.mothersIds(); + if (!motherIds1.empty() && !motherIds2.empty() && motherIds1[0] == motherIds2[0]) { + returnValue = true; + } + } // end association check + return returnValue; + } template bool buildDecayCandidateTwoBody(TTrackType const& t0, TTrackType const& t1, std::array vtx, Candidate& thisCandidate) @@ -392,9 +454,15 @@ struct Alice3strangenessFinder { thisCandidate.p[1] = thisCandidate.pDau0[1] + thisCandidate.pDau1[1]; thisCandidate.p[2] = thisCandidate.pDau0[2] + thisCandidate.pDau1[2]; const auto posSV = fitter.getPCACandidatePos(); - thisCandidate.posSV[0] = posSV[0]; - thisCandidate.posSV[1] = posSV[1]; - thisCandidate.posSV[2] = posSV[2]; + if (useOriginalTrackParams) { + thisCandidate.posSV[0] = t0.getX(); + thisCandidate.posSV[1] = t0.getY(); + thisCandidate.posSV[2] = t0.getZ(); + } else { + thisCandidate.posSV[0] = posSV[0]; + thisCandidate.posSV[1] = posSV[1]; + thisCandidate.posSV[2] = posSV[2]; + } std::array covA = {0}; std::array covB = {0}; @@ -427,6 +495,12 @@ struct Alice3strangenessFinder { thisCandidate.dcaToPV = calculateDCAStraightToPV(thisCandidate.posSV[0], thisCandidate.posSV[1], thisCandidate.posSV[2], thisCandidate.p[0], thisCandidate.p[1], thisCandidate.p[2], vtx[0], vtx[1], vtx[2]); + std::array dcaInfo; + dcaInfo[0] = dcaInfo[1] = 999.0f; // by default, take large value to make sure candidate accepted, TODO implement proper DCA calculation + thisCandidate.posDauDCAxy = dcaInfo[0]; + + dcaInfo[0] = dcaInfo[1] = 999.0f; // by default, take large value to make sure candidate accepted, TODO implement proper DCA calculation + thisCandidate.negDauDCAxy = dcaInfo[0]; } else { t0.getPxPyPzGlo(thisCandidate.pDau0); t1.getPxPyPzGlo(thisCandidate.pDau1); @@ -443,6 +517,8 @@ struct Alice3strangenessFinder { thisCandidate.dcaToPV = calculateDCAStraightToPV(thisCandidate.posSV[0], thisCandidate.posSV[1], thisCandidate.posSV[2], thisCandidate.p[0], thisCandidate.p[1], thisCandidate.p[2], vtx[0], vtx[1], vtx[2]); + thisCandidate.posDauDCAxy = 999.0f; + thisCandidate.negDauDCAxy = 999.0f; } return true; } @@ -484,18 +560,12 @@ struct Alice3strangenessFinder { } o2::track::TrackParCov pos = getTrackParCov(posTrack); - // if constexpr (requires { posTrack.pdgCode(); }) { - // if (posTrack.pdgCode() == kPiPlus) { - histos.fill(HIST("hPx"), posTrack.px()); - histos.fill(HIST("hPy"), posTrack.py()); - histos.fill(HIST("hPz"), posTrack.pz()); - // } - // } for (auto const& negTrack : negTracksGrouped) { if (!negTrack.isReconstructed()) { continue; // no ghost tracks } + o2::track::TrackParCov neg = getTrackParCov(negTrack); histos.fill(HIST("hV0Building"), 1.0); if (mcSameMotherCheck && !checkSameMother(posTrack, negTrack)) { @@ -503,68 +573,65 @@ struct Alice3strangenessFinder { } if (isK0Gun || isLambdaGun) { - // ACTS: pdg code attached to track - if constexpr (requires { posTrack.pdgCode(); }) { - if ((posTrack.pdgCode() != kPiPlus && negTrack.pdgCode() != kPiMinus) && isK0Gun) { - continue; - } - if ((posTrack.pdgCode() != kProton && negTrack.pdgCode() != kPiMinus) && isLambdaGun) { - continue; - } - } else { - // OTF: pdg code from mcParticle table - if (!posTrack.has_mcParticle() && !negTrack.has_mcParticle()) { - continue; - } - auto mcParticlePos = posTrack.template mcParticle_as(); - auto mcParticleNeg = negTrack.template mcParticle_as(); - if ((mcParticlePos.pdgCode() != kPiPlus && mcParticleNeg.pdgCode() != kPiMinus) && isK0Gun) { - continue; - } - if ((mcParticlePos.pdgCode() != kProton && mcParticleNeg.pdgCode() != kPiMinus) && isLambdaGun) { - continue; - } + if (!posTrack.has_mcParticle() || !negTrack.has_mcParticle()) { + continue; + } + auto mcParticlePos = posTrack.template mcParticle_as(); + auto mcParticleNeg = negTrack.template mcParticle_as(); + if ((mcParticlePos.pdgCode() != kPiPlus && mcParticleNeg.pdgCode() != kPiMinus) && isK0Gun) { + continue; + } + if ((mcParticlePos.pdgCode() != kProton && mcParticleNeg.pdgCode() != kPiMinus) && isLambdaGun) { + continue; } } - Candidate v0Cand; histos.fill(HIST("hV0Building"), 2.0); - o2::track::TrackParCov neg = getTrackParCov(negTrack); if (!buildDecayCandidateTwoBody(pos, neg, vtx, v0Cand)) { continue; // failed at building candidate } histos.fill(HIST("hV0Building"), 3.0); - // TODO: not all ACTS tracks have MC association, so this check is not possible for all candidates, fix is needed - // auto mcParticle1 = posTrack.template mcParticle_as(); - // if (mcParticle1.pdgCode() == kK0Short) { - // histos.fill(HIST("hV0Counter"), 0.5); - // } else if (mcParticle1.pdgCode() == kLambda0) { - // histos.fill(HIST("hV0Counter"), 1.5); - // } else if (mcParticle1.pdgCode() == kLambda0Bar) { - // histos.fill(HIST("hV0Counter"), 2.5); - // } else { - // histos.fill(HIST("hV0Counter"), 3.5); - // } - histos.fill(HIST("hPxPairs"), posTrack.px()); - histos.fill(HIST("hPyPairs"), posTrack.py()); - histos.fill(HIST("hPzPairs"), posTrack.pz()); - - histos.fill(HIST("hPxV0CandDaughter"), v0Cand.pDau0[0]); - histos.fill(HIST("hPyV0CandDaughter"), v0Cand.pDau0[1]); - histos.fill(HIST("hPzV0CandDaughter"), v0Cand.pDau0[2]); - + const float radiusV0 = std::hypot(v0Cand.posSV[0], v0Cand.posSV[1]); + std::array posSV = {v0Cand.posSV[0], v0Cand.posSV[1], v0Cand.posSV[2]}; + double p_pos_orig = sqrt(posTrack.px() * posTrack.px() + posTrack.py() * posTrack.py() + posTrack.pz() * posTrack.pz()); + double p_neg_orig = sqrt(negTrack.px() * negTrack.px() + negTrack.py() * negTrack.py() + negTrack.pz() * negTrack.pz()); + double p_pos_reprop = sqrt(v0Cand.pDau0[0] * v0Cand.pDau0[0] + v0Cand.pDau0[1] * v0Cand.pDau0[1] + v0Cand.pDau0[2] * v0Cand.pDau0[2]); + double p_neg_reprop = sqrt(v0Cand.pDau1[0] * v0Cand.pDau1[0] + v0Cand.pDau1[1] * v0Cand.pDau1[1] + v0Cand.pDau1[2] * v0Cand.pDau1[2]); + double cosOpeningAngleReprop = (v0Cand.pDau0[0] * v0Cand.pDau1[0] + v0Cand.pDau0[1] * v0Cand.pDau1[1] + v0Cand.pDau0[2] * v0Cand.pDau1[2]) / (sqrt(v0Cand.pDau0[0] * v0Cand.pDau0[0] + v0Cand.pDau0[1] * v0Cand.pDau0[1] + v0Cand.pDau0[2] * v0Cand.pDau0[2]) * sqrt(v0Cand.pDau1[0] * v0Cand.pDau1[0] + v0Cand.pDau1[1] * v0Cand.pDau1[1] + v0Cand.pDau1[2] * v0Cand.pDau1[2])); + double cosOpeningAngleOrig = (posTrack.px() * negTrack.px() + posTrack.py() * negTrack.py() + posTrack.pz() * negTrack.pz()) / (sqrt(posTrack.px() * posTrack.px() + posTrack.py() * posTrack.py() + posTrack.pz() * posTrack.pz()) * sqrt(negTrack.px() * negTrack.px() + negTrack.py() * negTrack.py() + negTrack.pz() * negTrack.pz())); + + if constexpr (requires { negTrack.secondaryVertexRadius(); }) { + histos.fill(HIST("hRadiusGenNeg"), negTrack.secondaryVertexRadius()); + histos.fill(HIST("hRadiusGenPos"), posTrack.secondaryVertexRadius()); + if (useGeneratedSVposition) { + posSV[0] = posTrack.secondaryVertexX(); + posSV[1] = posTrack.secondaryVertexY(); + posSV[2] = posTrack.secondaryVertexZ(); + } + } v0CandidateIndices(collision.globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(), -1); - v0CandidateCores(v0Cand.posSV[0], v0Cand.posSV[1], v0Cand.posSV[2], + v0CandidateCores(posSV[0], posSV[1], posSV[2], v0Cand.pDau0[0], v0Cand.pDau0[1], v0Cand.pDau0[2], v0Cand.pDau1[0], v0Cand.pDau1[1], v0Cand.pDau1[2], - v0Cand.dcaDau, posTrack.dcaXY(), negTrack.dcaXY(), + v0Cand.dcaDau, v0Cand.posDauDCAxy, v0Cand.negDauDCAxy, v0Cand.cosPA, v0Cand.dcaToPV); + histos.fill(HIST("hRadius"), radiusV0); + histos.fill(HIST("hPxPosRepropagated"), posTrack.px(), v0Cand.pDau0[0]); + histos.fill(HIST("hPyPosRepropagated"), posTrack.py(), v0Cand.pDau0[1]); + histos.fill(HIST("hPzPosRepropagated"), posTrack.pz(), v0Cand.pDau0[2]); + histos.fill(HIST("hPxNegRepropagated"), negTrack.px(), v0Cand.pDau1[0]); + histos.fill(HIST("hPyNegRepropagated"), negTrack.py(), v0Cand.pDau1[1]); + histos.fill(HIST("hPzNegRepropagated"), negTrack.pz(), v0Cand.pDau1[2]); + + histos.fill(HIST("hCosPhiRepropagated"), cosOpeningAngleOrig, cosOpeningAngleReprop); + histos.fill(HIST("hMomentumPosRepropagated"), p_pos_orig, p_pos_reprop); + histos.fill(HIST("hMomentumNegRepropagated"), p_neg_orig, p_neg_reprop); const float lambdaMassHypothesis = RecoDecay::m(std::array{std::array{v0Cand.pDau0[0], v0Cand.pDau0[1], v0Cand.pDau0[2]}, std::array{v0Cand.pDau1[0], v0Cand.pDau1[1], v0Cand.pDau1[2]}}, @@ -627,7 +694,7 @@ struct Alice3strangenessFinder { continue; // candidate outside of acceptance } - const float radiusV0 = std::hypot(v0Cand.posSV[0], v0Cand.posSV[1]); + // const float radiusV0 = std::hypot(v0Cand.posSV[0], v0Cand.posSV[1]); const float radiusCasc = std::hypot(cascCand.posSV[0], cascCand.posSV[1]); // tracks without update information (IU < 0) are not checked if (posTrack.trackIU() > 0.f && posTrack.trackIU() < radiusV0) { @@ -695,7 +762,7 @@ struct Alice3strangenessFinder { } // end posTrack } - void processMCTrueFromACTS(aod::McCollision const& collision, Alice3MCParticles const&) + void processMCTrueFromACTS(aod::McCollision const& collision, Alice3MCParticles const&, aod::McParticles const&) { auto negativeMCParticlesGrouped = negativeMCParticles->sliceByCached(aod::mcparticle::mcCollisionId, collision.globalIndex(), cache); @@ -730,6 +797,19 @@ struct Alice3strangenessFinder { if (!isLambda && isLambdaGun) { continue; } + if (isK0s && checkSameMotherGen(posParticle, negParticle)) { + histos.fill(HIST("K0Short/hPosDaughterGenPtEta"), posParticle.pt(), posParticle.eta()); + histos.fill(HIST("K0Short/hNegDaughterGenPtEta"), negParticle.pt(), negParticle.eta()); + } + if (isLambda && checkSameMotherGen(posParticle, negParticle)) { + histos.fill(HIST("Lambda/hPosDaughterGenPtEta"), posParticle.pt(), posParticle.eta()); + histos.fill(HIST("Lambda/hNegDaughterGenPtEta"), negParticle.pt(), negParticle.eta()); + } + if (isAntiLambda && checkSameMotherGen(posParticle, negParticle)) { + histos.fill(HIST("AntiLambda/hPosDaughterGenPtEta"), posParticle.pt(), posParticle.eta()); + histos.fill(HIST("AntiLambda/hNegDaughterGenPtEta"), negParticle.pt(), negParticle.eta()); + } + Candidate v0cand; std::vector v0DecayVertex; v0DecayVertex.push_back(negParticle.vx()); @@ -747,7 +827,7 @@ struct Alice3strangenessFinder { v0CandidateIndices(collision.globalIndex(), posParticle.globalIndex(), negParticle.globalIndex(), - 0); + -1); v0CandidateCores(v0cand.posSV[0], v0cand.posSV[1], v0cand.posSV[2], v0cand.pDau0[0], v0cand.pDau0[1], v0cand.pDau0[2], v0cand.pDau1[0], v0cand.pDau1[1], v0cand.pDau1[2], @@ -768,6 +848,69 @@ struct Alice3strangenessFinder { iPosPart++; } } + template + void processDaughterTrack(const TTracksGrouped& tracksGrouped, int daughterType) + { + // for the daughter track efficiency calculation + for (auto const& track : tracksGrouped) { + if (!track.isReconstructed()) { + continue; // no ghost tracks + } + if (!track.has_mcParticle()) { + continue; + } + float pt = std::hypot(track.px(), track.py()); + float eta = RecoDecay::eta(std::array{track.px(), track.py(), track.pz()}); + auto mcParticle = track.template mcParticle_as(); + if (mcParticle.has_mothers()) { + for (const auto& m1 : mcParticle.template mothers_as()) { + if (daughEff.analyseK0Daughters && m1.pdgCode() == kK0Short) { + if (daughterType == 0 && mcParticle.pdgCode() == kPiMinus) { + histos.fill(HIST("K0Short/hNegDaughterRecoTruePtEta"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("K0Short/hNegDaughterRecoPtEta"), pt, eta); + histos.fill(HIST("hPtResolutionNegative"), pt, mcParticle.pt()); + histos.fill(HIST("hPtRes1DNegDau"), (mcParticle.pt() - pt) / mcParticle.pt()); + } + if (daughterType == 1 && mcParticle.pdgCode() == kPiPlus) { + histos.fill(HIST("K0Short/hPosDaughterRecoTruePtEta"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("K0Short/hPosDaughterRecoPtEta"), pt, eta); + histos.fill(HIST("hPtResolutionPositive"), std::hypot(track.px(), track.py()), mcParticle.pt()); + histos.fill(HIST("hPtRes1DPosDau"), (mcParticle.pt() - pt) / mcParticle.pt()); + } + } + if (daughEff.analyseLambdaDaughters && m1.pdgCode() == kLambda0) { + if (daughterType == 0 && mcParticle.pdgCode() == kPiMinus) { + histos.fill(HIST("Lambda/hNegDaughterRecoTruePtEta"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Lambda/hNegDaughterRecoPtEta"), pt, eta); + histos.fill(HIST("hPtResolutionNegative"), pt, mcParticle.pt()); + histos.fill(HIST("hPtRes1DNegDau"), (mcParticle.pt() - pt) / mcParticle.pt()); + } + if (daughterType == 1 && mcParticle.pdgCode() == kProton) { + histos.fill(HIST("Lambda/hPosDaughterRecoTruePtEta"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Lambda/hPosDaughterRecoPtEta"), pt, eta); + histos.fill(HIST("hPtResolutionPositive"), pt, mcParticle.pt()); + histos.fill(HIST("hPtRes1DPosDau"), (mcParticle.pt() - pt) / mcParticle.pt()); + } + } + if (daughEff.analyseAntiLambdaDaughters && m1.pdgCode() == kLambda0Bar) { + if (daughterType == 0 && mcParticle.pdgCode() == kProtonBar) { + histos.fill(HIST("AntiLambda/hNegDaughterRecoTruePtEta"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("AntiLambda/hNegDaughterRecoPtEta"), pt, eta); + histos.fill(HIST("hPtResolutionNegative"), pt, mcParticle.pt()); + histos.fill(HIST("hPtRes1DNegDau"), (mcParticle.pt() - pt) / mcParticle.pt()); + } + if (daughterType == 1 && mcParticle.pdgCode() == kPiPlus) { + histos.fill(HIST("AntiLambda/hPosDaughterRecoTruePtEta"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("AntiLambda/hPosDaughterRecoPtEta"), pt, eta); + histos.fill(HIST("hPtResolutionPositive"), pt, mcParticle.pt()); + histos.fill(HIST("hPtRes1DPosDau"), (mcParticle.pt() - pt) / mcParticle.pt()); + } + } + } + } + } + } + // void processFindV0CandidateWithPid(aod::Collision const& collision, aod::McParticles const& mcParticles, Alice3TracksWPid const&) // { // auto negativeSecondaryPionsGrouped = negativeSecondaryPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -792,10 +935,31 @@ struct Alice3strangenessFinder { processFindV0CandidateNoPid(collision, negTracksGrouped, posTracksGrouped, bachTracksGrouped); } + void processDaughterTracksForEffACTS(aod::Collision const& collision, Alice3TracksACTS const&, aod::McParticles const&) + { + auto negTracksGrouped = negativeSecondaryTracksACTS->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto posTracksGrouped = positiveSecondaryTracksACTS->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + // auto bachTracksGrouped = bachelorTracksACTS->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + processDaughterTrack(negTracksGrouped, 0); + processDaughterTrack(posTracksGrouped, 1); + // processDaughterTrack(bachTracksGrouped,2); + } + void processDaughterTracksForEffOTF(aod::Collision const& collision, Alice3TracksOTF const&, aod::McParticles const&) + { + auto negTracksGrouped = negativeSecondaryTracksOTF->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto posTracksGrouped = positiveSecondaryTracksOTF->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + // auto bachTracksGrouped = bachelorTracksOTF->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + processDaughterTrack(negTracksGrouped, 0); + processDaughterTrack(posTracksGrouped, 1); + // processDaughterTrack(bachTracksGrouped,2); + } + PROCESS_SWITCH(Alice3strangenessFinder, processGenerated, "process generated information", true); PROCESS_SWITCH(Alice3strangenessFinder, processFindV0CandidateACTS, "find V0 without PID from ACTS reconstruction", true); PROCESS_SWITCH(Alice3strangenessFinder, processFindV0CandidateOTF, "find V0 without PID from OTF simulations", false); PROCESS_SWITCH(Alice3strangenessFinder, processMCTrueFromACTS, "process MC truth from ACTS", false); + PROCESS_SWITCH(Alice3strangenessFinder, processDaughterTracksForEffACTS, "process daughter trakcs from ACTS", true); + PROCESS_SWITCH(Alice3strangenessFinder, processDaughterTracksForEffOTF, "process daughter trakcs from ACTS", false); // PROCESS_SWITCH(alice3strangenessFinder, processFindV0CandidateWithPid, "find V0 with PID", false); }; From 42fbf87bc86b3446827a75fb3e8c2954bcc4c7c3 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Wed, 28 Oct 2026 15:11:31 +0100 Subject: [PATCH 4/4] new proces function for truth info, new histograms for efficiency as a function of radius --- ALICE3/Tasks/alice3Strangeness.cxx | 37 +++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/ALICE3/Tasks/alice3Strangeness.cxx b/ALICE3/Tasks/alice3Strangeness.cxx index 4733c899d16..b4d37ace7ce 100644 --- a/ALICE3/Tasks/alice3Strangeness.cxx +++ b/ALICE3/Tasks/alice3Strangeness.cxx @@ -101,6 +101,7 @@ struct Alice3Strangeness { Configurable cosPAngleSelection{"cosPAngleSelection", 0.97f, "cosine of pointing angle selection"}; Configurable dcaDaughtersToPVSelection{"dcaDaughtersToPVSelection", 0.05f, "DCA daughters to primary vertex selection"}; Configurable v0RadiusSelection{"v0RadiusSelection", 0.5f, "V0 radius selection"}; + Configurable v0MaxRadiusSelection{"v0MaxRadiusSelection", 3.0f, "V0 maximum radius selection"}; Configurable armenterosSelection{"armenterosSelection", 0.2f, "Armenteros-Podolanski selection in [0]* alpha"}; Configurable competingMassRejectionK0{"competingMassRejectionK0", 0.005f, "competing mass rejection for K0"}; Configurable competingMassRejectionLambda{"competingMassRejectionLambda", 0.01f, "competing mass rejection for Lambda"}; @@ -295,8 +296,10 @@ struct Alice3Strangeness { histos.add("reconstructedCandidates/hEtaDaughters", "hEtaDaughters", kTH1F, {histAxes.axisEta}); histos.add("reconstructedCandidates/K0/hMass", "hMass", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisEta}); histos.add("reconstructedCandidates/K0/hMass1D", "hMass1D", kTH1D, {histAxes.axisK0Mass}); + histos.add("reconstructedCandidates/K0/hMassRadius", "hMassRadius", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, {200, 0, 200}}); histos.add("reconstructedCandidates/Lambda/hMass", "hMass", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisEta}); histos.add("reconstructedCandidates/Lambda/hMass1D", "hMass1D", kTH1D, {histAxes.axisLambdaMass}); + histos.add("reconstructedCandidates/Lambda/hMassRadius", "hMassRadius", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, {200, 0, 200}}); histos.add("reconstructedCandidates/hArmeterosBeforeAllSelections", "hArmeterosBeforeAllSelections", kTH2D, {{100, -1.0f, 1.0f}, {200, 0.0f, 0.5f}}); histos.add("reconstructedCandidates/hArmeterosAfterAllSelections", "hArmeterosAfterAllSelections", kTH2D, {{100, -1.0f, 1.0f}, {200, 0.0f, 0.5f}}); histos.add("reconstructedCandidates/hPtEtaPosDaughter", "hPtEtaPosDaughter", kTH2D, {histAxes.axisPt, histAxes.axisEta}); @@ -402,6 +405,12 @@ struct Alice3Strangeness { } histos.addClone("reconstructedCandidates/Lambda/", "reconstructedCandidates/AntiLambda/"); + if (doprocessMCTruth) { + histos.add("mcTruth/K0Short/hPtRadius", "hPtRadius", kTH2D, {histAxes.axisPt, histAxes.axisRadius}); + histos.add("mcTruth/Lambda/hPtRadius", "hPtRadius", kTH2D, {histAxes.axisPt, histAxes.axisRadius}); + histos.add("mcTruth/AntiLambda/hPtRadius", "hPtRadius", kTH2D, {histAxes.axisPt, histAxes.axisRadius}); + } + appliedSelectionCheckMask = 0; if (!v0SelectionFlags.applyDCAdaughterSelection) { SETBIT(appliedSelectionCheckMask, 0); @@ -516,7 +525,7 @@ struct Alice3Strangeness { } histos.fill(HIST("hV0CandidateCounter"), 4.5); if (v0SelectionFlags.applyV0RadiusSelection) { - if (v0.v0radius() < v0SelectionValues.v0RadiusSelection) + if (v0.v0radius() < v0SelectionValues.v0RadiusSelection || v0.v0radius() > v0SelectionValues.v0MaxRadiusSelection) continue; } else { selectionCheck = v0.v0radius(); @@ -596,14 +605,17 @@ struct Alice3Strangeness { if (isK0) { histos.fill(HIST("reconstructedCandidates/K0/hMass"), v0.mK0Short(), v0.pt(), v0.eta()); histos.fill(HIST("reconstructedCandidates/K0/hMass1D"), v0.mK0Short()); + histos.fill(HIST("reconstructedCandidates/K0/hMassRadius"), v0.mK0Short(), v0.pt(), v0.v0radius()); } if (isLambda) { histos.fill(HIST("reconstructedCandidates/Lambda/hMass"), v0.mLambda(), v0.pt(), v0.eta()); histos.fill(HIST("reconstructedCandidates/Lambda/hMass1D"), v0.mLambda()); + histos.fill(HIST("reconstructedCandidates/Lambda/hMassRadius"), v0.mLambda(), v0.pt(), v0.v0radius()); } if (isAntiLambda) { histos.fill(HIST("reconstructedCandidates/AntiLambda/hMass"), v0.mAntiLambda(), v0.pt(), v0.eta()); histos.fill(HIST("reconstructedCandidates/AntiLambda/hMass1D"), v0.mAntiLambda()); + histos.fill(HIST("reconstructedCandidates/AntiLambda/hMassRadius"), v0.mAntiLambda(), v0.pt(), v0.v0radius()); } } } @@ -850,9 +862,32 @@ struct Alice3Strangeness { } } } + void processMCTruth(soa::Join const& mcParticles) + { + + for (auto const& mcPart : mcParticles) { + + if (!mcPart.isPhysicalPrimary()) { + continue; + } + + float ptmc = RecoDecay::sqrtSumOfSquares(mcPart.px(), mcPart.py()); + + if (mcPart.pdgCode() == 310) { + histos.fill(HIST("mcTruth/K0Short/hPtRadius"), ptmc, mcPart.secondaryVertexRadius()); + } + if (mcPart.pdgCode() == 3122) { + histos.fill(HIST("mcTruth/Lambda/hPtRadius"), ptmc, mcPart.secondaryVertexRadius()); + } + if (mcPart.pdgCode() == -3122) { + histos.fill(HIST("mcTruth/AntiLambda/hPtRadius"), ptmc, mcPart.secondaryVertexRadius()); + } + } + } PROCESS_SWITCH(Alice3Strangeness, processAllFindableCandidates, "", false); PROCESS_SWITCH(Alice3Strangeness, processFoundV0Candidates, "", true); + PROCESS_SWITCH(Alice3Strangeness, processMCTruth, "", true); PROCESS_SWITCH(Alice3Strangeness, processFoundCascadeCandidates, "", true); };