diff --git a/ALICE3/DataModel/OTFMulticharm.h b/ALICE3/DataModel/OTFMulticharm.h index 643d36c0adb..fe9cb6afc14 100644 --- a/ALICE3/DataModel/OTFMulticharm.h +++ b/ALICE3/DataModel/OTFMulticharm.h @@ -53,13 +53,6 @@ DECLARE_SOA_COLUMN(XiccDauDCA, xiccDauDCA, float); DECLARE_SOA_COLUMN(XiccDCAxy, xiccDCAxy, float); DECLARE_SOA_COLUMN(XiccDCAz, xiccDCAz, float); -DECLARE_SOA_COLUMN(BachDCAxy, bachDCAxy, float); -DECLARE_SOA_COLUMN(BachDCAz, bachDCAz, float); -DECLARE_SOA_COLUMN(PosDCAxy, posDCAxy, float); -DECLARE_SOA_COLUMN(PosDCAz, posDCAz, float); -DECLARE_SOA_COLUMN(NegDCAxy, negDCAxy, float); -DECLARE_SOA_COLUMN(NegDCAz, negDCAz, float); - DECLARE_SOA_COLUMN(Pi1cDCAxy, pi1cDCAxy, float); DECLARE_SOA_COLUMN(Pi1cDCAz, pi1cDCAz, float); DECLARE_SOA_COLUMN(Pi2cDCAxy, pi2cDCAxy, float); @@ -75,19 +68,9 @@ DECLARE_SOA_COLUMN(XicDistanceFromPV, xicDistanceFromPV, float); DECLARE_SOA_COLUMN(XiccProperLength, xiccProperLength, float); // Daughter info -DECLARE_SOA_COLUMN(PosPt, posPt, float); -DECLARE_SOA_COLUMN(PosEta, posEta, float); -DECLARE_SOA_COLUMN(NegPt, negPt, float); -DECLARE_SOA_COLUMN(NegEta, negEta, float); -DECLARE_SOA_COLUMN(BachPt, bachPt, float); -DECLARE_SOA_COLUMN(BachEta, bachEta, float); -DECLARE_SOA_COLUMN(BachPhi, bachPhi, float); DECLARE_SOA_COLUMN(Pi1cPt, pi1cPt, float); -DECLARE_SOA_COLUMN(Pi1cEta, pi1cEta, float); DECLARE_SOA_COLUMN(Pi2cPt, pi2cPt, float); -DECLARE_SOA_COLUMN(Pi2cEta, pi2cEta, float); DECLARE_SOA_COLUMN(PiccPt, piccPt, float); -DECLARE_SOA_COLUMN(PiccEta, piccEta, float); } // namespace otfmulticharm @@ -133,26 +116,6 @@ DECLARE_SOA_TABLE(MCharmCores, "AOD", "MCharmCores", otfmulticharm::PiccPt, otfmulticharm::LUTConfigId); -DECLARE_SOA_TABLE(MCharmExtra, "AOD", "MCharmExtra", - otfmulticharm::BachPt, - otfmulticharm::BachEta, - otfmulticharm::BachDCAxy, - otfmulticharm::BachDCAz, - - otfmulticharm::PosPt, - otfmulticharm::PosEta, - otfmulticharm::PosDCAxy, - otfmulticharm::PosDCAz, - - otfmulticharm::NegPt, - otfmulticharm::NegEta, - otfmulticharm::NegDCAxy, - otfmulticharm::NegDCAz, - - otfmulticharm::Pi1cEta, - otfmulticharm::Pi2cEta, - otfmulticharm::PiccEta); - } // namespace o2::aod #endif // ALICE3_DATAMODEL_OTFMULTICHARM_H_ diff --git a/ALICE3/DataModel/OTFStrangeness.h b/ALICE3/DataModel/OTFStrangeness.h index 2c985873bac..7169410b76d 100644 --- a/ALICE3/DataModel/OTFStrangeness.h +++ b/ALICE3/DataModel/OTFStrangeness.h @@ -41,7 +41,7 @@ DECLARE_SOA_INDEX_COLUMN(Collision, collision); DECLARE_SOA_INDEX_COLUMN_FULL(CascadeTrack, cascadeTrack, int, Tracks, "_Cascade"); //! DECLARE_SOA_INDEX_COLUMN_FULL(PosTrack, posTrack, int, Tracks, "_Pos"); //! DECLARE_SOA_INDEX_COLUMN_FULL(NegTrack, negTrack, int, Tracks, "_Neg"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(BachTrack, bachTrack, int, Tracks, "_Bach"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(Bachelor, bachelor, int, Tracks, "_Bach"); //! DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); @@ -53,6 +53,8 @@ DECLARE_SOA_COLUMN(CascRadius, cascRadius, float); DECLARE_SOA_COLUMN(CascRadiusMC, cascRadiusMC, float); DECLARE_SOA_COLUMN(MLambda, mLambda, float); DECLARE_SOA_COLUMN(MXi, mXi, float); +DECLARE_SOA_COLUMN(DCAXYCascToPV, dcaXYCascToPV, float); +DECLARE_SOA_COLUMN(DCAZCascToPV, dcaZCascToPV, float); // strangeness tracking DECLARE_SOA_COLUMN(FindableClusters, findableClusters, int); @@ -65,7 +67,7 @@ DECLARE_SOA_TABLE(UpgradeCascades, "AOD", "UPGRADECASCADES", otfcascade::CascadeTrackId, otfcascade::PosTrackId, otfcascade::NegTrackId, - otfcascade::BachTrackId, + otfcascade::BachelorId, otfcascade::DcaV0Daughters, otfcascade::DcaCascadeDaughters, otfcascade::V0Radius, @@ -74,12 +76,16 @@ DECLARE_SOA_TABLE(UpgradeCascades, "AOD", "UPGRADECASCADES", otfcascade::MLambda, otfcascade::MXi, otfcascade::FindableClusters, - otfcascade::FoundClusters); + otfcascade::FoundClusters, + otfcascade::DCAXYCascToPV, + otfcascade::DCAZCascToPV); using UpgradeCascade = UpgradeCascades::iterator; DECLARE_SOA_TABLE(A3CascadeMcLabels, "AOD", "A3CASCADEMCLABELS", o2::soa::Index<>, otfcascade::McParticleId); +DECLARE_SOA_TABLE(UpgradeCascadeMcLabels, "AOD", "UPGRADECASCMCLAB", + o2::soa::Index<>, otfcascade::McParticleId); namespace casc_pid { diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 69b9419f9b9..9b54eb9f648 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -144,6 +144,7 @@ struct OnTheFlyTracker { Produces tableUpgradeCascades; Produces tableOTFLUTConfigId; Produces tableUpgradeV0s; + Produces tableUpgradeCascadeMcLabels; // optionally produced, empty (to be tuned later) Produces tableStoredTracksExtra; // base table, extend later @@ -1315,8 +1316,9 @@ struct OnTheFlyTracker { } // end cascade kink building // +-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+ + double dcaXY{999.f}, dcaZ{999.f}; + o2::track::TrackParCov trackParametrization(xiTrackParCov); if (cascadeDecaySettings.doXiQA) { - double dcaXY{-1.}, dcaZ{-1.}; if (reconstructedCascade) { getHist(TH2, histPath + "hRecoXi")->Fill(xiDecayRadius2D, mcParticle.pt()); getHist(TH1, histPath + "hMassLambda")->Fill(thisCascade.mLambda); @@ -1325,40 +1327,37 @@ struct OnTheFlyTracker { getHist(TH2, histPath + "h2dDeltaPtVsPt")->Fill(thisCascade.pt, (mcParticle.pt() - thisCascade.pt) / thisCascade.pt); getHist(TH2, histPath + "h2dDeltaEtaVsPt")->Fill(thisCascade.pt, mcParticle.eta() - thisCascade.eta); getHist(TH2, histPath + "hFoundVsFindable")->Fill(thisCascade.findableClusters, thisCascade.foundClusters); - - o2::track::TrackParCov trackParametrization(xiTrackParCov); - trackParametrization.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo); getHist(TH2, histPath + "h2dDCAxyCascade")->Fill(trackParametrization.getPt(), dcaXY * 1e+4); // in microns, please getHist(TH2, histPath + "h2dDCAzCascade")->Fill(trackParametrization.getPt(), dcaZ * 1e+4); // in microns, please } if (isReco[0]) { getHist(TH2, histPath + "hRecoPiFromXi")->Fill(xiDecayRadius2D, cascadeDecayProducts[0].Pt()); - o2::track::TrackParCov trackParametrizationCascProng0(xiTrackParCov); - if (populateTracksDCA && xiTrackParCov.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo)) { // FIXME: this is not the right trackParametrization, need to propagate the bachelor track + o2::track::TrackParCov trackParametrizationBachelor(xiTrackParCov); + if (populateTracksDCA && trackParametrizationBachelor.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo)) { dcaXY = dcaInfo.getY(); dcaZ = dcaInfo.getZ(); - getHist(TH2, histPath + "h2dDCAxyCascadeBachelor")->Fill(trackParametrizationCascProng0.getPt(), dcaXY * 1e+4); // in microns, please - getHist(TH2, histPath + "h2dDCAzCascadeBachelor")->Fill(trackParametrizationCascProng0.getPt(), dcaZ * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAxyCascadeBachelor")->Fill(trackParametrizationBachelor.getPt(), dcaXY * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAzCascadeBachelor")->Fill(trackParametrizationBachelor.getPt(), dcaZ * 1e+4); // in microns, please } } if (isReco[1]) { getHist(TH2, histPath + "hRecoPiFromLa")->Fill(laDecayRadius2D, cascadeDecayProducts[1].Pt()); - o2::track::TrackParCov trackParametrizationCascProng1(xiTrackParCov); - if (populateTracksDCA && xiTrackParCov.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo)) { // FIXME: this is not the right trackParametrization, need to propagate the negative pion track + o2::track::TrackParCov trackParametrizationNegative(xiTrackParCov); + if (populateTracksDCA && trackParametrizationNegative.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo)) { dcaXY = dcaInfo.getY(); dcaZ = dcaInfo.getZ(); - getHist(TH2, histPath + "h2dDCAxyCascadeNegative")->Fill(trackParametrizationCascProng1.getPt(), dcaXY * 1e+4); // in microns, please - getHist(TH2, histPath + "h2dDCAzCascadeNegative")->Fill(trackParametrizationCascProng1.getPt(), dcaZ * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAxyCascadeNegative")->Fill(trackParametrizationNegative.getPt(), dcaXY * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAzCascadeNegative")->Fill(trackParametrizationNegative.getPt(), dcaZ * 1e+4); // in microns, please } } if (isReco[2]) { getHist(TH2, histPath + "hRecoPrFromLa")->Fill(laDecayRadius2D, cascadeDecayProducts[2].Pt()); - o2::track::TrackParCov trackParametrizationCascProng2(xiTrackParCov); - if (populateTracksDCA && xiTrackParCov.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo)) { // FIXME: this is not the right trackParametrization, need to propagate the positive proton track + o2::track::TrackParCov trackParametrizationPositive(xiTrackParCov); + if (populateTracksDCA && trackParametrizationPositive.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo)) { dcaXY = dcaInfo.getY(); dcaZ = dcaInfo.getZ(); - getHist(TH2, histPath + "h2dDCAxyCascadePositive")->Fill(trackParametrizationCascProng2.getPt(), dcaXY * 1e+4); // in microns, please - getHist(TH2, histPath + "h2dDCAzCascadePositive")->Fill(trackParametrizationCascProng2.getPt(), dcaZ * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAxyCascadePositive")->Fill(trackParametrizationPositive.getPt(), dcaXY * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAzCascadePositive")->Fill(trackParametrizationPositive.getPt(), dcaZ * 1e+4); // in microns, please } } } @@ -1368,7 +1367,11 @@ struct OnTheFlyTracker { return; } + // Make sure the xi variables are stored in dcaXY and dcaZ + trackParametrization.propagateToDCA(primaryVertex, mMagneticField, &dcaInfo); + // populate Cascades + tableUpgradeCascadeMcLabels(mcParticle.globalIndex()); tableUpgradeCascades(tableCollisions.lastIndex(), thisCascade.cascadeTrackId, thisCascade.positiveId, @@ -1382,7 +1385,8 @@ struct OnTheFlyTracker { thisCascade.mLambda, thisCascade.mXi, thisCascade.findableClusters, - thisCascade.foundClusters); + thisCascade.foundClusters, + dcaXY, dcaZ); } /// Function to study V0s and fill the relevant histograms diff --git a/ALICE3/TableProducer/alice3MulticharmFinder.cxx b/ALICE3/TableProducer/alice3MulticharmFinder.cxx index 6b7d98f64a5..65f4393dcf2 100644 --- a/ALICE3/TableProducer/alice3MulticharmFinder.cxx +++ b/ALICE3/TableProducer/alice3MulticharmFinder.cxx @@ -20,6 +20,8 @@ // Uses specific ALICE 3 PID and performance for studying // HF decays. Work in progress: use at your own risk! +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "ALICE3/DataModel/A3DecayFinderTables.h" #include "ALICE3/DataModel/OTFCollision.h" #include "ALICE3/DataModel/OTFMulticharm.h" @@ -76,21 +78,17 @@ using namespace o2::framework::expressions; using Alice3Tracks = soa::Join; using Alice3Collision = soa::Join::iterator; +using FullCascadeCandidates = soa::Join; struct Alice3MulticharmFinder { - SliceCache cache; - Produces multiCharmIdx; Produces multiCharmCore; - Produces multiCharmExtra; - - // Operation and minimisation criteria + SliceCache cache; struct : ConfigurableGroup { std::string prefix = "derivedTable"; // JSON group name Configurable fillMCharmIdx{"fillMCharmIdx", true, "fill MCharmIdx[] tables (careful: memory)"}; Configurable fillMCharmCore{"fillMCharmCore", true, "fill MCharmCores[] tables (careful: memory)"}; - Configurable fillMCharmExtra{"fillMCharmExtra", false, "fill MCharmExtra[] tables (careful: memory)"}; } derivedTable; struct : ConfigurableGroup { @@ -109,7 +107,6 @@ struct Alice3MulticharmFinder { Configurable cfgMagneticField{"cfgMagneticField", 20.0f, "Magnetic field (in kilogauss) if value not found from geo provider"}; Configurable doDCAplots{"doDCAplots", true, "do daughter prong DCA plots for D mesons"}; Configurable mcSameMotherCheck{"mcSameMotherCheck", true, "check if tracks come from the same MC mother"}; - Configurable> minNTracks{"minNTracks", {-1}, "Minimum number of tracks"}; Configurable xiMinConstDCAxy{"xiMinConstDCAxy", 0.0005f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable xiMinConstDCAz{"xiMinConstDCAz", 0.0005f, "[0] in |DCAxy| > [0]+[1]/pT"}; @@ -172,6 +169,7 @@ struct Alice3MulticharmFinder { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; std::map histPointers; + std::string histPath; std::vector savedConfigs; // Constants @@ -193,38 +191,35 @@ struct Alice3MulticharmFinder { Partition piccTracks = ((aod::a3DecayMap::decayMap & TrackSelectionPicc) == TrackSelectionPicc) && aod::track::signed1Pt > 0.0f && 1.0f / nabs(aod::track::signed1Pt) > piccMinPt&& nabs(aod::track::dcaXY) > piccMinConstDCAxy + piccMinPtDepDCAxy* nabs(aod::track::signed1Pt) && nabs(aod::track::dcaZ) > piccMinConstDCAz + piccMinPtDepDCAz* nabs(aod::track::signed1Pt); - // Helper struct to pass candidate information + // Helper structs to pass candidate information struct { - // decay properties - float dca; - float mass; - float pt; - float eta; - std::array xyz; - std::array prong0mom; - std::array prong1mom; - std::array prong2mom; - std::array parentTrackCovMatrix; + float radius{}; + o2::track::TrackParCov trackParCov; + } thisXiCandidate; + + struct { + float dca{}; + float mass{}; + float pt{}; + float eta{}; + std::array xyz{}; + std::array prong0mom{}; + std::array prong1mom{}; + std::array prong2mom{}; + std::array parentTrackCovMatrix{}; } thisXicCandidate; struct { - float dca; - float mass; - float pt; - float eta; - std::array xyz; - std::array prong0mom; - std::array prong1mom; - std::array parentTrackCovMatrix; + float dca{}; + float mass{}; + float pt{}; + float eta{}; + std::array xyz{}; + std::array prong0mom{}; + std::array prong1mom{}; + std::array parentTrackCovMatrix{}; } thisXiccCandidate; - struct ProngInfo { - float pt = 1e+10; - float eta = 1e+10; - float dcaXY = 1e+10; - float dcaZ = 1e+10; - }; - template bool buildDecayCandidateTwoBody(TTrackType const& t0, TTrackType const& t1, float mass0, float mass1) { @@ -301,12 +296,8 @@ struct Alice3MulticharmFinder { } template - bool buildDecayCandidateThreeBody(TTrackType1 const& prong0, TTrackType2 const& prong1, TTrackType3 const& prong2, float p0mass, float p1mass, float p2mass) + bool buildDecayCandidateThreeBody(TTrackType1 t0, TTrackType2 t1, TTrackType3 t2, float p0mass, float p1mass, float p2mass) { - o2::track::TrackParCov t0 = getTrackParCov(prong0); - o2::track::TrackParCov t1 = getTrackParCov(prong1); - o2::track::TrackParCov t2 = getTrackParCov(prong2); - //}-{}-{}-{}-{}-{}-{}-{}-{}-{} // Move close to minima int nCand = 0; @@ -508,7 +499,6 @@ struct Alice3MulticharmFinder { } savedConfigs.push_back(icfg); - const std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; // This histogram bookkeeps the attempts at DCA minimization and their eventual // failure rates. @@ -601,332 +591,338 @@ struct Alice3MulticharmFinder { } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - void processFindXicc(Alice3Collision const& collision, Alice3Tracks const& tracks, aod::McParticles const&, aod::UpgradeCascades const& cascades) + template + void processFindXicc(const TCollision& collision, const TCascadeCandidate& xi, const THfProngsGrouped& picTracksGrouped, const THfProngsGrouped& piccTracksGrouped) { - const std::string histPath = "Configuration_" + std::to_string(collision.lutConfigId()) + "/"; - initDetectorConfiguration(collision.lutConfigId()); - - GET_HIST(TH1, histPath + "hNCollisions")->Fill(1); - GET_HIST(TH1, histPath + "hNTracks")->Fill(tracks.size()); - if (tracks.size() < minNTracks.value[collision.lutConfigId()]) { - return; - } - - GET_HIST(TH1, histPath + "hNCollisions")->Fill(2); - // group with this collision - // n.b. cascades do not need to be grouped, being used directly in iterator-grouping - auto picTracksGrouped = picTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto piccTracksGrouped = piccTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + uint32_t nCombinationsC = 0; + for (auto const& pi1c : picTracksGrouped) { + if (mcSameMotherCheck && !checkSameMother(xi, pi1c)) { + continue; + } - for (auto const& track : tracks) { - if (BIT_CHECK(track.decayMap(), kTruePiFromXiC)) { - GET_HIST(TH2, histPath + "h2dDCAxyVsPtPiFromXiC")->Fill(track.pt(), track.dcaXY() * ToMicrons); - GET_HIST(TH2, histPath + "h2dDCAxyVsPtPiFromXiC")->Fill(track.pt(), track.dcaZ() * ToMicrons); + if (xi.posTrackId() == pi1c.globalIndex() || xi.negTrackId() == pi1c.globalIndex() || xi.bachelorId() == pi1c.globalIndex()) { + continue; // avoid using any track that was already used } - if (BIT_CHECK(track.decayMap(), kTruePiFromXiCC)) { - GET_HIST(TH2, histPath + "h2dDCAxyVsPtPiFromXiCC")->Fill(track.pt(), track.dcaXY() * ToMicrons); - GET_HIST(TH2, histPath + "h2dDCAxyVsPtPiFromXiCC")->Fill(track.pt(), track.dcaZ() * ToMicrons); + + if (pi1c.pt() < picMinPt) { + continue; // too low momentum } - } - for (auto const& xiCand : cascades) { - auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track - GET_HIST(TH1, histPath + "hMassXi")->Fill(xiCand.mXi()); - GET_HIST(TH2, histPath + "h2dDCAxyVsPtXiFromXiC")->Fill(xi.pt(), xi.dcaXY() * ToMicrons); - GET_HIST(TH2, histPath + "h2dDCAzVsPtXiFromXiC")->Fill(xi.pt(), xi.dcaZ() * ToMicrons); + GET_HIST(TH1, histPath + "hPi1cPt")->Fill(pi1c.pt()); + // second pion from XiC decay for starts here + for (auto const& pi2c : picTracksGrouped) { + if (mcSameMotherCheck && !checkSameMother(xi, pi2c)) { + continue; // keep only if same mother + } - if (std::fabs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > xiMassWindow) { - continue; // out of mass region - } + if (pi1c.globalIndex() >= pi2c.globalIndex()) { + continue; // avoid same-mother, avoid double-counting + } - uint32_t nCombinationsC = 0; - if (!BIT_CHECK(xi.decayMap(), kTrueXiFromXiC)) { - continue; - } + if (xi.posTrackId() == pi2c.globalIndex() || xi.negTrackId() == pi2c.globalIndex() || xi.bachelorId() == pi2c.globalIndex()) { + continue; // avoid using any track that was already used + } - if (std::fabs(xi.dcaXY()) < xiMinConstDCAxy || std::fabs(xi.dcaZ()) < xiMinConstDCAz) { - continue; // likely a primary xi - } + if (pi2c.pt() < picMinPt) { + continue; // too low momentum + } - GET_HIST(TH1, histPath + "hDCAxyXi")->Fill(xi.dcaXY() * ToMicrons); - GET_HIST(TH1, histPath + "hDCAzXi")->Fill(xi.dcaZ() * ToMicrons); - if (xiCand.cascRadius() < xiMinDecayRadius) { - continue; - } + // if I am here, it means this is a triplet to be considered for XiC vertexing. + // will now attempt to build a three-body decay candidate with these three track rows. + nCombinationsC++; + GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(0.0f); + GET_HIST(TH1, histPath + "hPi2cPt")->Fill(pi2c.pt()); - GET_HIST(TH1, histPath + "hMinXiDecayRadius")->Fill(xiCand.cascRadius()); - for (auto const& pi1c : picTracksGrouped) { - if (mcSameMotherCheck && !checkSameMother(xi, pi1c)) { + o2::track::TrackParCov pi1cTrack = getTrackParCov(pi1c); + o2::track::TrackParCov pi2cTrack = getTrackParCov(pi2c); + if (!buildDecayCandidateThreeBody(thisXiCandidate.trackParCov, pi1cTrack, pi2cTrack, o2::constants::physics::MassXiMinus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged)) { + continue; // failed at building candidate + } + + GET_HIST(TH1, histPath + "hDCAXiCDaughters")->Fill(thisXicCandidate.dca * ToMicrons); + if (std::fabs(thisXicCandidate.mass - o2::constants::physics::MassXiCPlus) > xicMassWindow) { + continue; // out of mass region + } + + GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(1.0f); + const std::array momentumC = {thisXicCandidate.prong0mom[0] + thisXicCandidate.prong1mom[0] + thisXicCandidate.prong2mom[0], + thisXicCandidate.prong0mom[1] + thisXicCandidate.prong1mom[1] + thisXicCandidate.prong2mom[1], + thisXicCandidate.prong0mom[2] + thisXicCandidate.prong1mom[2] + thisXicCandidate.prong2mom[2]}; + + o2::track::TrackParCov xicTrack(thisXicCandidate.xyz, momentumC, thisXicCandidate.parentTrackCovMatrix, +1); + float xicDecayRadius2D = std::hypot(thisXicCandidate.xyz[0], thisXicCandidate.xyz[1]); + if (xicDecayRadius2D < xicMinDecayRadius) { + continue; // do not take if radius too small, likely a primary combination + } + + GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(2.0f); + GET_HIST(TH1, histPath + "hMinXiCDecayRadius")->Fill(xicDecayRadius2D * ToMicrons); + if (xicDecayRadius2D > thisXiCandidate.radius) { continue; } - if (xiCand.posTrackId() == pi1c.globalIndex() || xiCand.negTrackId() == pi1c.globalIndex() || xiCand.bachTrackId() == pi1c.globalIndex()) { - continue; // avoid using any track that was already used + GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(3.0f); + GET_HIST(TH2, histPath + "hXiRadiusVsXicRadius")->Fill(thisXiCandidate.radius * ToMicrons, xicDecayRadius2D * ToMicrons); + o2::dataformats::DCA dcaInfo; + float xicdcaXY = 1e+10, xicdcaZ = 1e+10; + o2::track::TrackParCov xicTrackCopy(xicTrack); // paranoia + o2::vertexing::PVertex primaryVertex; + primaryVertex.setXYZ(collision.posX(), collision.posY(), collision.posZ()); + + if (xicTrackCopy.propagateToDCA(primaryVertex, cfgMagneticField, &dcaInfo)) { + xicdcaXY = dcaInfo.getY(); + xicdcaZ = dcaInfo.getZ(); } - if (pi1c.pt() < picMinPt) { - continue; // too low momentum + if (std::fabs(xicdcaXY) < xicMaxDCAxy || std::fabs(xicdcaZ) < xicMaxDCAz) { + continue; // likely a primary xic } - GET_HIST(TH1, histPath + "hPi1cPt")->Fill(pi1c.pt()); - // second pion from XiC decay for starts here - for (auto const& pi2c : picTracksGrouped) { - if (mcSameMotherCheck && !checkSameMother(xi, pi2c)) { - continue; // keep only if same mother - } + GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(4.0f); + GET_HIST(TH1, histPath + "hDCAxyXiC")->Fill(std::fabs(xicdcaXY * ToMicrons)); + GET_HIST(TH1, histPath + "hDCAzXiC")->Fill(std::fabs(xicdcaZ * ToMicrons)); + GET_HIST(TH1, histPath + "hMassXiC")->Fill(thisXicCandidate.mass); - if (pi1c.globalIndex() >= pi2c.globalIndex()) { - continue; // avoid same-mother, avoid double-counting + // attempt XiCC finding + uint32_t nCombinationsCC = 0; + for (auto const& picc : piccTracksGrouped) { + if (mcSameMotherCheck && !checkSameMotherExtra(xi, picc)) { + continue; } - if (xiCand.posTrackId() == pi2c.globalIndex() || xiCand.negTrackId() == pi2c.globalIndex() || xiCand.bachTrackId() == pi2c.globalIndex()) { + if (xi.posTrackId() == picc.globalIndex() || xi.negTrackId() == picc.globalIndex() || xi.bachelorId() == picc.globalIndex()) { continue; // avoid using any track that was already used } - if (pi2c.pt() < picMinPt) { + if (picc.pt() < piccMinPt) { continue; // too low momentum } - GET_HIST(TH1, histPath + "hPi2cPt")->Fill(pi2c.pt()); - // if I am here, it means this is a triplet to be considered for XiC vertexing. - // will now attempt to build a three-body decay candidate with these three track rows. - nCombinationsC++; - GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(0.0f); - - if (!buildDecayCandidateThreeBody(xi, pi1c, pi2c, o2::constants::physics::MassXiMinus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged)) { + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(0.0f); + GET_HIST(TH1, histPath + "hPiccPt")->Fill(picc.pt()); + o2::track::TrackParCov piccTrack = getTrackParCov(picc); + nCombinationsCC++; + if (!buildDecayCandidateTwoBody(xicTrack, piccTrack, o2::constants::physics::MassXiCPlus, o2::constants::physics::MassPionCharged)) { continue; // failed at building candidate } - GET_HIST(TH1, histPath + "hDCAXiCDaughters")->Fill(thisXicCandidate.dca * ToMicrons); - if (std::fabs(thisXicCandidate.mass - o2::constants::physics::MassXiCPlus) > xicMassWindow) { - continue; // out of mass region - } - - GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(1.0f); - const std::array momentumC = { - thisXicCandidate.prong0mom[0] + thisXicCandidate.prong1mom[0] + thisXicCandidate.prong2mom[0], - thisXicCandidate.prong0mom[1] + thisXicCandidate.prong1mom[1] + thisXicCandidate.prong2mom[1], - thisXicCandidate.prong0mom[2] + thisXicCandidate.prong1mom[2] + thisXicCandidate.prong2mom[2]}; + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(1.0f); + GET_HIST(TH1, histPath + "hDCAXiCCDaughters")->Fill(thisXiccCandidate.dca * ToMicrons); + const std::array momentumCC = { + thisXiccCandidate.prong0mom[0] + thisXiccCandidate.prong1mom[0], + thisXiccCandidate.prong0mom[1] + thisXiccCandidate.prong1mom[1], + thisXiccCandidate.prong0mom[2] + thisXiccCandidate.prong1mom[2]}; - o2::track::TrackParCov xicTrack(thisXicCandidate.xyz, momentumC, thisXicCandidate.parentTrackCovMatrix, +1); - float xicDecayRadius2D = std::hypot(thisXicCandidate.xyz[0], thisXicCandidate.xyz[1]); - if (xicDecayRadius2D < xicMinDecayRadius) { + o2::track::TrackParCov xiccTrack(thisXiccCandidate.xyz, momentumCC, thisXiccCandidate.parentTrackCovMatrix, +2); + float xiccDecayRadius2D = std::hypot(thisXiccCandidate.xyz[0], thisXiccCandidate.xyz[1]); + if (xiccDecayRadius2D < xiccMinDecayRadius) { continue; // do not take if radius too small, likely a primary combination } - GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(2.0f); - GET_HIST(TH1, histPath + "hMinXiCDecayRadius")->Fill(xicDecayRadius2D * ToMicrons); - if (xicDecayRadius2D > xiCand.cascRadius()) { - continue; + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(2.0f); + float totalMomentumC = std::hypot(momentumC[0], momentumC[1], momentumC[2]); + float decayLengthXiC = std::hypot(thisXicCandidate.xyz[0] - thisXiccCandidate.xyz[0], + thisXicCandidate.xyz[1] - thisXiccCandidate.xyz[1], + thisXicCandidate.xyz[2] - thisXiccCandidate.xyz[2]); + float xicProperLength = decayLengthXiC * thisXicCandidate.mass / totalMomentumC; + + if (xicProperLength < xicMinProperLength || xicProperLength > xicMaxProperLength) { + continue; // likely background } - GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(3.0f); - GET_HIST(TH2, histPath + "hXiRadiusVsXicRadius")->Fill(xiCand.cascRadius() * ToMicrons, xicDecayRadius2D * ToMicrons); - o2::dataformats::DCA dcaInfo; - float xicdcaXY = 1e+10, xicdcaZ = 1e+10; - o2::track::TrackParCov xicTrackCopy(xicTrack); // paranoia - o2::vertexing::PVertex primaryVertex; - primaryVertex.setXYZ(collision.posX(), collision.posY(), collision.posZ()); - - if (xicTrackCopy.propagateToDCA(primaryVertex, cfgMagneticField, &dcaInfo)) { - xicdcaXY = dcaInfo.getY(); - xicdcaZ = dcaInfo.getZ(); + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(3.0f); + GET_HIST(TH1, histPath + "hProperLengthXiC")->Fill(xicProperLength * ToMicrons); + float xicDistanceFromPV = std::hypot(thisXicCandidate.xyz[0] - collision.posX(), + thisXicCandidate.xyz[1] - collision.posY(), + thisXicCandidate.xyz[2] - collision.posZ()); + float xicDecayDistanceFromPV = xicDistanceFromPV * thisXicCandidate.mass / totalMomentumC; + if (xicDecayDistanceFromPV < xicMinDecayDistanceFromPV) { + continue; // too close to PV } - if (std::fabs(xicdcaXY) < xicMaxDCAxy || std::fabs(xicdcaZ) < xicMaxDCAz) { - continue; // likely a primary xic + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(4.0f); + GET_HIST(TH1, histPath + "hMinXicDecayDistanceFromPV")->Fill(xicDecayDistanceFromPV * ToMicrons); + float totalMomentumCC = std::hypot(momentumCC[0], momentumCC[1], momentumCC[2]); + float decayLengthXiCC = std::hypot(thisXiccCandidate.xyz[0] - collision.posX(), + thisXiccCandidate.xyz[1] - collision.posY(), + thisXiccCandidate.xyz[2] - collision.posZ()); + float xiccProperLength = decayLengthXiCC * thisXiccCandidate.mass / totalMomentumCC; + if (xiccProperLength < xiccMinProperLength || xiccProperLength > xiccMaxProperLength) { + continue; // likely background } - GET_HIST(TH1, histPath + "hCharmBuilding")->Fill(4.0f); - GET_HIST(TH1, histPath + "hDCAxyXiC")->Fill(std::fabs(xicdcaXY * ToMicrons)); - GET_HIST(TH1, histPath + "hDCAzXiC")->Fill(std::fabs(xicdcaZ * ToMicrons)); - GET_HIST(TH1, histPath + "hMassXiC")->Fill(thisXicCandidate.mass); + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(5.0f); + GET_HIST(TH1, histPath + "hProperLengthXiCC")->Fill(xiccProperLength * ToMicrons); + if (xiccDecayRadius2D > xicDecayRadius2D) { + continue; // XiCC should decay before XiC + } - // attempt XiCC finding - uint32_t nCombinationsCC = 0; - for (auto const& picc : piccTracksGrouped) { - if (mcSameMotherCheck && !checkSameMotherExtra(xi, picc)) { - continue; - } + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(6.0f); + GET_HIST(TH2, histPath + "hXicRadiusVsXiccRadius")->Fill(xicDecayRadius2D * ToMicrons, xiccDecayRadius2D * ToMicrons); + float xiccdcaXY = 1e+10, xiccdcaZ = 1e+10; + if (xiccTrack.propagateToDCA(primaryVertex, cfgMagneticField, &dcaInfo)) { + xiccdcaXY = dcaInfo.getY(); + xiccdcaZ = dcaInfo.getZ(); + } - if (xiCand.posTrackId() == picc.globalIndex() || xiCand.negTrackId() == picc.globalIndex() || xiCand.bachTrackId() == picc.globalIndex()) { - continue; // avoid using any track that was already used - } + if (std::fabs(xiccdcaXY) > xiccMaxDCAxy || std::fabs(xiccdcaZ) > xiccMaxDCAz) { + continue; // not pointing to PV + } - if (picc.pt() < piccMinPt) { - continue; // too low momentum - } + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(7.0f); + GET_HIST(TH1, histPath + "hDCAxyXiCC")->Fill(xiccdcaXY * ToMicrons); + GET_HIST(TH1, histPath + "hDCAzXiCC")->Fill(xiccdcaZ * ToMicrons); + if (std::fabs(thisXiccCandidate.eta) > xiccMaxEta) { + continue; // not in central barrel + } - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(0.0f); - GET_HIST(TH1, histPath + "hPiccPt")->Fill(picc.pt()); - o2::track::TrackParCov piccTrack = getTrackParCov(picc); - nCombinationsCC++; - if (!buildDecayCandidateTwoBody(xicTrack, piccTrack, o2::constants::physics::MassXiCPlus, o2::constants::physics::MassPionCharged)) { - continue; // failed at building candidate - } + GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(8.0f); + GET_HIST(TH1, histPath + "hMassXiCC")->Fill(thisXiccCandidate.mass); + GET_HIST(TH1, histPath + "hPtXiCC")->Fill(thisXiccCandidate.pt); + GET_HIST(TH1, histPath + "hEtaXiCC")->Fill(thisXiccCandidate.eta); + GET_HIST(TH3, histPath + "h3dMassXiCC")->Fill(thisXiccCandidate.pt, thisXiccCandidate.eta, thisXiccCandidate.mass); + + GET_HIST(TH1, histPath + "hPi1cDCAxy")->Fill(std::abs(pi1c.dcaXY() * ToMicrons)); + GET_HIST(TH1, histPath + "hPi1cDCAz")->Fill(std::abs(pi1c.dcaZ() * ToMicrons)); + GET_HIST(TH1, histPath + "hPi2cDCAxy")->Fill(std::abs(pi2c.dcaXY() * ToMicrons)); + GET_HIST(TH1, histPath + "hPi2cDCAz")->Fill(std::abs(pi2c.dcaZ() * ToMicrons)); + GET_HIST(TH1, histPath + "hPiccDCAxy")->Fill(std::abs(picc.dcaXY() * ToMicrons)); + GET_HIST(TH1, histPath + "hPiccDCAz")->Fill(std::abs(picc.dcaZ() * ToMicrons)); + + // produce multi-charm table for posterior analysis + if (derivedTable.fillMCharmIdx) { + multiCharmIdx(xi.globalIndex(), + pi1c.globalIndex(), + pi2c.globalIndex(), + picc.globalIndex()); + } - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(1.0f); - GET_HIST(TH1, histPath + "hDCAXiCCDaughters")->Fill(thisXiccCandidate.dca * ToMicrons); - const std::array momentumCC = { - thisXiccCandidate.prong0mom[0] + thisXiccCandidate.prong1mom[0], - thisXiccCandidate.prong0mom[1] + thisXiccCandidate.prong1mom[1], - thisXiccCandidate.prong0mom[2] + thisXiccCandidate.prong1mom[2]}; - - o2::track::TrackParCov xiccTrack(thisXiccCandidate.xyz, momentumCC, thisXiccCandidate.parentTrackCovMatrix, +2); - float xiccDecayRadius2D = std::hypot(thisXiccCandidate.xyz[0], thisXiccCandidate.xyz[1]); - if (xiccDecayRadius2D < xiccMinDecayRadius) { - continue; // do not take if radius too small, likely a primary combination - } + if (derivedTable.fillMCharmCore) { + multiCharmCore(thisXiccCandidate.mass, thisXiccCandidate.pt, + thisXiccCandidate.eta, thisXiccCandidate.dca, + thisXicCandidate.mass, thisXicCandidate.pt, + thisXicCandidate.eta, thisXicCandidate.dca, + xi.dcaXYCascToPV(), xi.dcaZCascToPV(), + xicdcaXY, xicdcaZ, + xiccdcaXY, xiccdcaZ, + pi1c.dcaXY(), pi1c.dcaZ(), + pi2c.dcaXY(), pi2c.dcaZ(), + picc.dcaXY(), picc.dcaZ(), + xicDecayRadius2D, xiccDecayRadius2D, + xicProperLength, + xicDecayDistanceFromPV, + xiccProperLength, + pi1c.pt(), pi2c.pt(), picc.pt(), + collision.lutConfigId()); + } + } + GET_HIST(TH1, histPath + "hCombinationsXiCC")->Fill(nCombinationsCC); + } + } + GET_HIST(TH1, histPath + "hCombinationsXiC")->Fill(nCombinationsC); + } + //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(2.0f); - GET_HIST(TH1, histPath + "hDCAXiCCDaughters")->Fill(thisXiccCandidate.dca * ToMicrons); - float totalMomentumC = std::hypot(momentumC[0], momentumC[1], momentumC[2]); - float decayLengthXiC = std::hypot( - thisXicCandidate.xyz[0] - thisXiccCandidate.xyz[0], - thisXicCandidate.xyz[1] - thisXiccCandidate.xyz[1], - thisXicCandidate.xyz[2] - thisXiccCandidate.xyz[2]); - float xicProperLength = decayLengthXiC * thisXicCandidate.mass / totalMomentumC; - - if (xicProperLength < xicMinProperLength || xicProperLength > xicMaxProperLength) { - continue; // likely background - } + template + void configureCollision(const TCollision& collision, const TTracks& tracks) + { + histPath = "Configuration_" + std::to_string(collision.lutConfigId()) + "/"; + initDetectorConfiguration(collision.lutConfigId()); - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(3.0f); - GET_HIST(TH1, histPath + "hProperLengthXiC")->Fill(xicProperLength * ToMicrons); - float xicDistanceFromPV = std::hypot( - thisXicCandidate.xyz[0] - collision.posX(), - thisXicCandidate.xyz[1] - collision.posY(), - thisXicCandidate.xyz[2] - collision.posZ()); - float xicDecayDistanceFromPV = xicDistanceFromPV * thisXicCandidate.mass / totalMomentumC; - if (xicDecayDistanceFromPV < xicMinDecayDistanceFromPV) { - continue; // too close to PV - } + GET_HIST(TH1, histPath + "hNCollisions")->Fill(1); + GET_HIST(TH1, histPath + "hNCollisions")->Fill(2); + GET_HIST(TH1, histPath + "hNTracks")->Fill(tracks.size()); - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(4.0f); - GET_HIST(TH1, histPath + "hMinXicDecayDistanceFromPV")->Fill(xicDecayDistanceFromPV * ToMicrons); - float totalMomentumCC = std::hypot(momentumCC[0], momentumCC[1], momentumCC[2]); - float decayLengthXiCC = std::hypot( - thisXiccCandidate.xyz[0] - collision.posX(), - thisXiccCandidate.xyz[1] - collision.posY(), - thisXiccCandidate.xyz[2] - collision.posZ()); - float xiccProperLength = decayLengthXiCC * thisXiccCandidate.mass / totalMomentumCC; - if (xiccProperLength < xiccMinProperLength || xiccProperLength > xicMaxProperLength) { - continue; // likely background - } + for (auto const& track : tracks) { + if (BIT_CHECK(track.decayMap(), kTruePiFromXiC)) { + GET_HIST(TH2, histPath + "h2dDCAxyVsPtPiFromXiC")->Fill(track.pt(), track.dcaXY() * ToMicrons); + GET_HIST(TH2, histPath + "h2dDCAzVsPtPiFromXiC")->Fill(track.pt(), track.dcaZ() * ToMicrons); + } + if (BIT_CHECK(track.decayMap(), kTruePiFromXiCC)) { + GET_HIST(TH2, histPath + "h2dDCAxyVsPtPiFromXiCC")->Fill(track.pt(), track.dcaXY() * ToMicrons); + GET_HIST(TH2, histPath + "h2dDCAzVsPtPiFromXiCC")->Fill(track.pt(), track.dcaZ() * ToMicrons); + } + } + } - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(5.0f); - GET_HIST(TH1, histPath + "hProperLengthXiCC")->Fill(xiccProperLength * ToMicrons); - if (xiccDecayRadius2D > xicDecayRadius2D) { - continue; // XiCC should decay before XiC - } + void processPerfectBuilder(Alice3Collision const& collision, soa::Join const& cascades, Alice3Tracks const& tracks, aod::McParticles const&) + { + configureCollision(collision, tracks); + auto picTracksGrouped = picTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto piccTracksGrouped = piccTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(6.0f); - GET_HIST(TH2, histPath + "hXicRadiusVsXiccRadius")->Fill(xicDecayRadius2D * ToMicrons, xiccDecayRadius2D * ToMicrons); - float xiccdcaXY = 1e+10, xiccdcaZ = 1e+10; - if (xiccTrack.propagateToDCA(primaryVertex, cfgMagneticField, &dcaInfo)) { - xiccdcaXY = dcaInfo.getY(); - xiccdcaZ = dcaInfo.getZ(); - } + for (const auto& xiCand : cascades) { + auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track + if (std::fabs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > xiMassWindow) { + continue; // out of mass region + } - if (std::fabs(xiccdcaXY) > xiccMaxDCAxy || std::fabs(xiccdcaZ) > xiccMaxDCAz) { - continue; // not pointing to PV - } + if (!BIT_CHECK(xi.decayMap(), kTrueXiFromXiC)) { + continue; + } - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(7.0f); - GET_HIST(TH1, histPath + "hDCAxyXiCC")->Fill(xiccdcaXY * ToMicrons); - GET_HIST(TH1, histPath + "hDCAzXiCC")->Fill(xiccdcaZ * ToMicrons); - if (std::fabs(thisXiccCandidate.eta) > xiccMaxEta) { - continue; // not in central barrel - } + if (std::fabs(xi.dcaXY()) < xiMinConstDCAxy || std::fabs(xi.dcaZ()) < xiMinConstDCAz) { + continue; // likely a primary xi + } - GET_HIST(TH1, histPath + "hMultiCharmBuilding")->Fill(8.0f); - GET_HIST(TH1, histPath + "hMassXiCC")->Fill(thisXiccCandidate.mass); - GET_HIST(TH1, histPath + "hPtXiCC")->Fill(thisXiccCandidate.pt); - GET_HIST(TH1, histPath + "hEtaXiCC")->Fill(thisXiccCandidate.eta); - GET_HIST(TH3, histPath + "h3dMassXiCC")->Fill(thisXiccCandidate.pt, thisXiccCandidate.eta, thisXiccCandidate.mass); - - GET_HIST(TH1, histPath + "hPi1cDCAxy")->Fill(std::abs(pi1c.dcaXY() * ToMicrons)); - GET_HIST(TH1, histPath + "hPi1cDCAz")->Fill(std::abs(pi1c.dcaZ() * ToMicrons)); - GET_HIST(TH1, histPath + "hPi2cDCAxy")->Fill(std::abs(pi2c.dcaXY() * ToMicrons)); - GET_HIST(TH1, histPath + "hPi2cDCAz")->Fill(std::abs(pi2c.dcaZ() * ToMicrons)); - GET_HIST(TH1, histPath + "hPiccDCAxy")->Fill(std::abs(picc.dcaXY() * ToMicrons)); - GET_HIST(TH1, histPath + "hPiccDCAz")->Fill(std::abs(picc.dcaZ() * ToMicrons)); - - // produce multi-charm table for posterior analysis - if (derivedTable.fillMCharmIdx) { - multiCharmIdx( - xiCand.globalIndex(), - pi1c.globalIndex(), pi2c.globalIndex(), - picc.globalIndex()); - } + if (xiCand.cascRadius() < xiMinDecayRadius) { + continue; + } - if (derivedTable.fillMCharmCore) { - multiCharmCore( - thisXiccCandidate.mass, thisXiccCandidate.pt, - thisXiccCandidate.eta, thisXiccCandidate.dca, - thisXicCandidate.mass, thisXicCandidate.pt, - thisXicCandidate.eta, thisXicCandidate.dca, - xi.dcaXY(), xi.dcaZ(), - xicdcaXY, xicdcaZ, - xiccdcaXY, xiccdcaZ, - pi1c.dcaXY(), pi1c.dcaZ(), - pi2c.dcaXY(), pi2c.dcaZ(), - picc.dcaXY(), picc.dcaZ(), - xicDecayRadius2D, xiccDecayRadius2D, - xicProperLength, - xicDecayDistanceFromPV, - xiccProperLength, - pi1c.pt(), pi2c.pt(), picc.pt(), - collision.lutConfigId()); - } + GET_HIST(TH1, histPath + "hMassXi")->Fill(xiCand.mXi()); + GET_HIST(TH2, histPath + "h2dDCAxyVsPtXiFromXiC")->Fill(xi.pt(), xi.dcaXY() * ToMicrons); + GET_HIST(TH2, histPath + "h2dDCAzVsPtXiFromXiC")->Fill(xi.pt(), xi.dcaZ() * ToMicrons); + GET_HIST(TH1, histPath + "hDCAxyXi")->Fill(xi.dcaXY() * ToMicrons); + GET_HIST(TH1, histPath + "hDCAzXi")->Fill(xi.dcaZ() * ToMicrons); + GET_HIST(TH1, histPath + "hMinXiDecayRadius")->Fill(xiCand.cascRadius()); + thisXiCandidate.radius = xiCand.cascRadius(); + thisXiCandidate.trackParCov = getTrackParCov(xi); + processFindXicc(collision, xiCand, picTracksGrouped, piccTracksGrouped); + } + } - if (derivedTable.fillMCharmExtra) { - ProngInfo bachelor, positive, negative; - if (xiCand.has_bachTrack()) { - auto bach = xiCand.bachTrack_as(); // de-reference bach track - bachelor.pt = bach.pt(); - bachelor.eta = bach.eta(); - bachelor.dcaXY = bach.dcaXY(); - bachelor.dcaZ = bach.dcaZ(); - } + void processStraBuilder(Alice3Collision const& collision, FullCascadeCandidates const& cascadeCandidates, Alice3Tracks const& tracks, aod::McParticles const&) + { + configureCollision(collision, tracks); + auto picTracksGrouped = picTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto piccTracksGrouped = piccTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - if (xiCand.has_negTrack()) { - auto neg = xiCand.negTrack_as(); // de-reference neg track - negative.pt = neg.pt(); - negative.eta = neg.eta(); - negative.dcaXY = neg.dcaXY(); - negative.dcaZ = neg.dcaZ(); - } + for (const auto& xiCand : cascadeCandidates) { + if (std::fabs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > xiMassWindow) { + continue; // out of mass region + } - if (xiCand.has_posTrack()) { - auto pos = xiCand.posTrack_as(); // de-reference pos track - positive.pt = pos.pt(); - positive.eta = pos.eta(); - positive.dcaXY = pos.dcaXY(); - positive.dcaZ = pos.dcaZ(); - } + if (std::fabs(xiCand.dcaXYCascToPV()) < xiMinConstDCAxy || std::fabs(xiCand.dcaZCascToPV()) < xiMinConstDCAz) { + continue; // likely a primary xi + } - multiCharmExtra( - bachelor.pt, bachelor.eta, - bachelor.dcaXY, bachelor.dcaZ, - positive.pt, positive.eta, - positive.dcaXY, positive.dcaZ, - negative.pt, negative.eta, - negative.dcaXY, negative.dcaZ, - pi1c.eta(), pi2c.eta(), picc.eta()); - } - } - GET_HIST(TH1, histPath + "hCombinationsXiCC")->Fill(nCombinationsCC); - } + if (xiCand.cascradius() < xiMinDecayRadius) { + continue; } - GET_HIST(TH1, histPath + "hCombinationsXiC")->Fill(nCombinationsC); + + GET_HIST(TH1, histPath + "hMassXi")->Fill(xiCand.mXi()); + GET_HIST(TH2, histPath + "h2dDCAxyVsPtXiFromXiC")->Fill(xiCand.pt(), xiCand.dcaXYCascToPV() * ToMicrons); + GET_HIST(TH2, histPath + "h2dDCAzVsPtXiFromXiC")->Fill(xiCand.pt(), xiCand.dcaZCascToPV() * ToMicrons); + GET_HIST(TH1, histPath + "hDCAxyXi")->Fill(xiCand.dcaXYCascToPV() * ToMicrons); + GET_HIST(TH1, histPath + "hDCAzXi")->Fill(xiCand.dcaZCascToPV() * ToMicrons); + GET_HIST(TH1, histPath + "hMinXiDecayRadius")->Fill(xiCand.cascradius()); + + const std::array cascSV = {xiCand.x(), xiCand.y(), xiCand.z()}; + const std::array cascP = {xiCand.px(), xiCand.py(), xiCand.pz()}; + const int chargeCascade = (xiCand.sign() > 0) ? 1 : -1; + static constexpr int NCovMatElements = 21; + std::array cascCovMat{}; + std::copy(xiCand.covMat(), xiCand.covMat() + NCovMatElements, cascCovMat.begin()); + thisXiCandidate.radius = xiCand.cascradius(); + thisXiCandidate.trackParCov = o2::track::TrackParCov(cascSV, cascP, cascCovMat, chargeCascade); + processFindXicc(collision, xiCand, picTracksGrouped, piccTracksGrouped); } } - //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* //*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<* PROCESS_SWITCH(Alice3MulticharmFinder, processGenerated, "fill MC-only histograms", true); - PROCESS_SWITCH(Alice3MulticharmFinder, processFindXicc, "find XiCC baryons", true); + PROCESS_SWITCH(Alice3MulticharmFinder, processStraBuilder, "find XiCC baryons", false); + PROCESS_SWITCH(Alice3MulticharmFinder, processPerfectBuilder, "find XiCC baryons", true); //*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<* }; diff --git a/ALICE3/TableProducer/alice3strangenessFinder.cxx b/ALICE3/TableProducer/alice3strangenessFinder.cxx index 01a33fbeab1..4ac78a5effa 100644 --- a/ALICE3/TableProducer/alice3strangenessFinder.cxx +++ b/ALICE3/TableProducer/alice3strangenessFinder.cxx @@ -77,8 +77,9 @@ struct Alice3strangenessFinder { Produces v0CandidateIndices; // contains V0 candidate indices Produces v0CandidateCores; // contains V0 candidate core information Produces tableStoredCascCores; // contains stored cascade core information - Produces tableA3CascadeMcLabels; // contains cascade core MC labels Produces tableCascIndices; // contains cascade indices + Produces tableCascCovs; // contains cascade cov matrix + Produces tableA3CascadeMcLabels; // contains cascade core MC labels Configurable buildCascade{"buildCascade", false, "build cascade candidates"}; Configurable nSigmaTOF{"nSigmaTOF", 5.0f, "Nsigma for TOF PID (if enabled)"}; @@ -631,6 +632,7 @@ struct Alice3strangenessFinder { histos.fill(HIST("CascadeBuilding/hXiMass"), massXi); histos.fill(HIST("CascadeBuilding/hOmegaMass"), massOm); + tableCascCovs(cascCand.parentTrackCovMatrix.data()); tableA3CascadeMcLabels(cascCand.index); tableCascIndices(0, // cascade index, dummy value posTrack.globalIndex(), diff --git a/ALICE3/Tasks/alice3Multicharm.cxx b/ALICE3/Tasks/alice3Multicharm.cxx index a27f6f937ba..fc4cd76c769 100644 --- a/ALICE3/Tasks/alice3Multicharm.cxx +++ b/ALICE3/Tasks/alice3Multicharm.cxx @@ -49,16 +49,13 @@ using namespace o2::ml; using namespace o2::framework; using namespace o2::framework::expressions; -using MultiCharmTracksPID = soa::Join; -using MultiCharmTracksFull = soa::Join; - struct Alice3Multicharm { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - o2::ml::OnnxModel bdtMCharm; - std::map metadata; - o2::ccdb::CcdbApi ccdbApi; - Service ccdb; + o2::ml::OnnxModel bdtMCharm{}; + std::map metadata{}; + o2::ccdb::CcdbApi ccdbApi{}; + static constexpr float ToMicrons = 1e+4; struct : ConfigurableGroup { std::string prefix = "bdt"; // JSON group name @@ -187,15 +184,6 @@ struct Alice3Multicharm { hMCharmBuilding->GetXaxis()->SetBinLabel(21, "xiccMaxProperLength"); hMCharmBuilding->GetXaxis()->SetBinLabel(22, "xicMinDecayDistanceFromPV"); - if (doprocessXiccExtra) { - histos.add("XiccProngs/h3dPos", "h3dPos; Xicc pT (GeV/#it(c)); Pos pT (GeV/#it(c)); Pos #eta", kTH3D, {axisPt, axisPt, axisEta}); - histos.add("XiccProngs/h3dNeg", "h3dNeg; Xicc pT (GeV/#it(c)); Neg pT (GeV/#it(c)); Neg #eta", kTH3D, {axisPt, axisPt, axisEta}); - histos.add("XiccProngs/h3dBach", "h3dBach; Xicc pT (GeV/#it(c)); Bach pT (GeV/#it(c)); Bach #eta", kTH3D, {axisPt, axisPt, axisEta}); - histos.add("XiccProngs/h3dPi1c", "h3dPi1c; Xicc pT (GeV/#it(c)); Pi1c pT (GeV/#it(c)); Pi1c #eta", kTH3D, {axisPt, axisPt, axisEta}); - histos.add("XiccProngs/h3dPi2c", "h3dPi2c; Xicc pT (GeV/#it(c)); Pi2c pT (GeV/#it(c)); Pi2c #eta", kTH3D, {axisPt, axisPt, axisEta}); - histos.add("XiccProngs/h3dPicc", "h3dPicc; Xicc pT (GeV/#it(c)); Picc pT (GeV/#it(c)); Picc #eta", kTH3D, {axisPt, axisPt, axisEta}); - } - histos.add("hXiccMass", "hXiccMass", kTH1D, {axisXiccMass}); histos.add("hXicMass", "hXicMass", kTH1D, {axisXicMass}); histos.add("hXiccPt", "hXiccPt", kTH1D, {axisPt}); @@ -204,7 +192,6 @@ struct Alice3Multicharm { histos.add("hConfigId", "hConfigId", kTH1D, {{11, -0.5, 10.5}}); if (bdt.enableML) { - ccdb->setURL(bdt.ccdbUrl.value); if (bdt.loadModelsFromCCDB) { ccdbApi.init(bdt.ccdbUrl); LOG(info) << "Fetching model for timestamp: " << bdt.timestampCCDB.value; @@ -264,25 +251,25 @@ struct Alice3Multicharm { const int icfg = xiccCand.lutConfigId(); histos.fill(HIST("hConfigId"), icfg); - histos.fill(HIST("CandidateQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * 1e+4); - histos.fill(HIST("CandidateQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * 1e+4); - histos.fill(HIST("CandidateQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * 1e+4)); - histos.fill(HIST("CandidateQA/hDCAzXi"), std::fabs(xiccCand.xiDCAz() * 1e+4)); - histos.fill(HIST("CandidateQA/hDCAxyXic"), std::fabs(xiccCand.xicDCAxy() * 1e+4)); - histos.fill(HIST("CandidateQA/hDCAzXic"), std::fabs(xiccCand.xicDCAz() * 1e+4)); - histos.fill(HIST("CandidateQA/hDCAxyXicc"), std::fabs(xiccCand.xiccDCAxy() * 1e+4)); - histos.fill(HIST("CandidateQA/hDCAzXicc"), std::fabs(xiccCand.xiccDCAz() * 1e+4)); - histos.fill(HIST("CandidateQA/hDecayRadiusXic"), xiccCand.xicDecayRadius2D() * 1e+4); - histos.fill(HIST("CandidateQA/hDecayRadiusXicc"), xiccCand.xiccDecayRadius2D() * 1e+4); - histos.fill(HIST("CandidateQA/hDecayDistanceFromPVXic"), xiccCand.xicDistanceFromPV() * 1e+4); - histos.fill(HIST("CandidateQA/hProperLengthXic"), xiccCand.xicProperLength() * 1e+4); - histos.fill(HIST("CandidateQA/hProperLengthXicc"), xiccCand.xiccProperLength() * 1e+4); - histos.fill(HIST("CandidateQA/hPi1cDCAxy"), xiccCand.pi1cDCAxy() * 1e+4); - histos.fill(HIST("CandidateQA/hPi1cDCAz"), xiccCand.pi1cDCAz() * 1e+4); - histos.fill(HIST("CandidateQA/hPi2cDCAxy"), xiccCand.pi2cDCAxy() * 1e+4); - histos.fill(HIST("CandidateQA/hPi2cDCAz"), xiccCand.pi2cDCAz() * 1e+4); - histos.fill(HIST("CandidateQA/hPiccDCAxy"), xiccCand.piccDCAxy() * 1e+4); - histos.fill(HIST("CandidateQA/hPiccDCAz"), xiccCand.piccDCAz() * 1e+4); + histos.fill(HIST("CandidateQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * ToMicrons); + histos.fill(HIST("CandidateQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * ToMicrons); + histos.fill(HIST("CandidateQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * ToMicrons)); + histos.fill(HIST("CandidateQA/hDCAzXi"), std::fabs(xiccCand.xiDCAz() * ToMicrons)); + histos.fill(HIST("CandidateQA/hDCAxyXic"), std::fabs(xiccCand.xicDCAxy() * ToMicrons)); + histos.fill(HIST("CandidateQA/hDCAzXic"), std::fabs(xiccCand.xicDCAz() * ToMicrons)); + histos.fill(HIST("CandidateQA/hDCAxyXicc"), std::fabs(xiccCand.xiccDCAxy() * ToMicrons)); + histos.fill(HIST("CandidateQA/hDCAzXicc"), std::fabs(xiccCand.xiccDCAz() * ToMicrons)); + histos.fill(HIST("CandidateQA/hDecayRadiusXic"), xiccCand.xicDecayRadius2D() * ToMicrons); + histos.fill(HIST("CandidateQA/hDecayRadiusXicc"), xiccCand.xiccDecayRadius2D() * ToMicrons); + histos.fill(HIST("CandidateQA/hDecayDistanceFromPVXic"), xiccCand.xicDistanceFromPV() * ToMicrons); + histos.fill(HIST("CandidateQA/hProperLengthXic"), xiccCand.xicProperLength() * ToMicrons); + histos.fill(HIST("CandidateQA/hProperLengthXicc"), xiccCand.xiccProperLength() * ToMicrons); + histos.fill(HIST("CandidateQA/hPi1cDCAxy"), xiccCand.pi1cDCAxy() * ToMicrons); + histos.fill(HIST("CandidateQA/hPi1cDCAz"), xiccCand.pi1cDCAz() * ToMicrons); + histos.fill(HIST("CandidateQA/hPi2cDCAxy"), xiccCand.pi2cDCAxy() * ToMicrons); + histos.fill(HIST("CandidateQA/hPi2cDCAz"), xiccCand.pi2cDCAz() * ToMicrons); + histos.fill(HIST("CandidateQA/hPiccDCAxy"), xiccCand.piccDCAxy() * ToMicrons); + histos.fill(HIST("CandidateQA/hPiccDCAz"), xiccCand.piccDCAz() * ToMicrons); histos.fill(HIST("CandidateQA/hPi1cPt"), xiccCand.pi1cPt()); histos.fill(HIST("CandidateQA/hPi2cPt"), xiccCand.pi2cPt()); histos.fill(HIST("CandidateQA/hPiccPt"), xiccCand.piccPt()); @@ -324,25 +311,25 @@ struct Alice3Multicharm { histos.fill(HIST("BDT/hBDTScoreVsXiccPtBackground"), xiccCand.xiccPt(), bdtPredictedBackground); histos.fill(HIST("BDT/h3dBDTScoreBackground"), xiccCand.xiccPt(), xiccCand.xiccMass(), bdtPredictedBackground); - histos.fill(HIST("BDT/hDCAXicDaughters"), bdtPredictedSignal, xiccCand.xicDauDCA() * 1e+4); - histos.fill(HIST("BDT/hDCAXiccDaughters"), bdtPredictedSignal, xiccCand.xiccDauDCA() * 1e+4); - histos.fill(HIST("BDT/hDCAxyXi"), bdtPredictedSignal, std::fabs(xiccCand.xiDCAxy() * 1e+4)); - histos.fill(HIST("BDT/hDCAzXi"), bdtPredictedSignal, std::fabs(xiccCand.xiDCAz() * 1e+4)); - histos.fill(HIST("BDT/hDCAxyXic"), bdtPredictedSignal, std::fabs(xiccCand.xicDCAxy() * 1e+4)); - histos.fill(HIST("BDT/hDCAzXic"), bdtPredictedSignal, std::fabs(xiccCand.xicDCAz() * 1e+4)); - histos.fill(HIST("BDT/hDCAxyXicc"), bdtPredictedSignal, std::fabs(xiccCand.xiccDCAxy() * 1e+4)); - histos.fill(HIST("BDT/hDCAzXicc"), bdtPredictedSignal, std::fabs(xiccCand.xiccDCAz() * 1e+4)); - histos.fill(HIST("BDT/hDecayRadiusXic"), bdtPredictedSignal, xiccCand.xicDecayRadius2D() * 1e+4); - histos.fill(HIST("BDT/hDecayRadiusXicc"), bdtPredictedSignal, xiccCand.xiccDecayRadius2D() * 1e+4); - histos.fill(HIST("BDT/hDecayDistanceFromPVXic"), bdtPredictedSignal, xiccCand.xicDistanceFromPV() * 1e+4); - histos.fill(HIST("BDT/hProperLengthXic"), bdtPredictedSignal, xiccCand.xicProperLength() * 1e+4); - histos.fill(HIST("BDT/hProperLengthXicc"), bdtPredictedSignal, xiccCand.xiccProperLength() * 1e+4); - histos.fill(HIST("BDT/hPi1cDCAxy"), bdtPredictedSignal, xiccCand.pi1cDCAxy() * 1e+4); - histos.fill(HIST("BDT/hPi1cDCAz"), bdtPredictedSignal, xiccCand.pi1cDCAz() * 1e+4); - histos.fill(HIST("BDT/hPi2cDCAxy"), bdtPredictedSignal, xiccCand.pi2cDCAxy() * 1e+4); - histos.fill(HIST("BDT/hPi2cDCAz"), bdtPredictedSignal, xiccCand.pi2cDCAz() * 1e+4); - histos.fill(HIST("BDT/hPiccDCAxy"), bdtPredictedSignal, xiccCand.piccDCAxy() * 1e+4); - histos.fill(HIST("BDT/hPiccDCAz"), bdtPredictedSignal, xiccCand.piccDCAz() * 1e+4); + histos.fill(HIST("BDT/hDCAXicDaughters"), bdtPredictedSignal, xiccCand.xicDauDCA() * ToMicrons); + histos.fill(HIST("BDT/hDCAXiccDaughters"), bdtPredictedSignal, xiccCand.xiccDauDCA() * ToMicrons); + histos.fill(HIST("BDT/hDCAxyXi"), bdtPredictedSignal, std::fabs(xiccCand.xiDCAxy() * ToMicrons)); + histos.fill(HIST("BDT/hDCAzXi"), bdtPredictedSignal, std::fabs(xiccCand.xiDCAz() * ToMicrons)); + histos.fill(HIST("BDT/hDCAxyXic"), bdtPredictedSignal, std::fabs(xiccCand.xicDCAxy() * ToMicrons)); + histos.fill(HIST("BDT/hDCAzXic"), bdtPredictedSignal, std::fabs(xiccCand.xicDCAz() * ToMicrons)); + histos.fill(HIST("BDT/hDCAxyXicc"), bdtPredictedSignal, std::fabs(xiccCand.xiccDCAxy() * ToMicrons)); + histos.fill(HIST("BDT/hDCAzXicc"), bdtPredictedSignal, std::fabs(xiccCand.xiccDCAz() * ToMicrons)); + histos.fill(HIST("BDT/hDecayRadiusXic"), bdtPredictedSignal, xiccCand.xicDecayRadius2D() * ToMicrons); + histos.fill(HIST("BDT/hDecayRadiusXicc"), bdtPredictedSignal, xiccCand.xiccDecayRadius2D() * ToMicrons); + histos.fill(HIST("BDT/hDecayDistanceFromPVXic"), bdtPredictedSignal, xiccCand.xicDistanceFromPV() * ToMicrons); + histos.fill(HIST("BDT/hProperLengthXic"), bdtPredictedSignal, xiccCand.xicProperLength() * ToMicrons); + histos.fill(HIST("BDT/hProperLengthXicc"), bdtPredictedSignal, xiccCand.xiccProperLength() * ToMicrons); + histos.fill(HIST("BDT/hPi1cDCAxy"), bdtPredictedSignal, xiccCand.pi1cDCAxy() * ToMicrons); + histos.fill(HIST("BDT/hPi1cDCAz"), bdtPredictedSignal, xiccCand.pi1cDCAz() * ToMicrons); + histos.fill(HIST("BDT/hPi2cDCAxy"), bdtPredictedSignal, xiccCand.pi2cDCAxy() * ToMicrons); + histos.fill(HIST("BDT/hPi2cDCAz"), bdtPredictedSignal, xiccCand.pi2cDCAz() * ToMicrons); + histos.fill(HIST("BDT/hPiccDCAxy"), bdtPredictedSignal, xiccCand.piccDCAxy() * ToMicrons); + histos.fill(HIST("BDT/hPiccDCAz"), bdtPredictedSignal, xiccCand.piccDCAz() * ToMicrons); histos.fill(HIST("BDT/hPi1cPt"), bdtPredictedSignal, xiccCand.pi1cPt()); histos.fill(HIST("BDT/hPi2cPt"), bdtPredictedSignal, xiccCand.pi2cPt()); histos.fill(HIST("BDT/hPiccPt"), bdtPredictedSignal, xiccCand.piccPt()); @@ -351,162 +338,131 @@ struct Alice3Multicharm { histos.fill(HIST("hMCharmBuilding"), 0); if (xiccCand.xicDauDCA() > xicMaxDauDCA) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 1); } + histos.fill(HIST("hMCharmBuilding"), 1); if (xiccCand.xiccDauDCA() > xiccMaxDauDCA) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 2); } + histos.fill(HIST("hMCharmBuilding"), 2); if (std::fabs(xiccCand.xiDCAxy()) < xiMinDCAxy) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 3); } + histos.fill(HIST("hMCharmBuilding"), 3); if (std::fabs(xiccCand.xiDCAz()) < xiMinDCAz) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 4); } + histos.fill(HIST("hMCharmBuilding"), 4); if (std::fabs(xiccCand.pi1cDCAxy()) < picMinDCAxy) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 5); } + histos.fill(HIST("hMCharmBuilding"), 5); if (std::fabs(xiccCand.pi1cDCAz()) < picMinDCAz) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 6); } + histos.fill(HIST("hMCharmBuilding"), 6); if (std::fabs(xiccCand.pi2cDCAxy()) < picMinDCAxy) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 7); } + histos.fill(HIST("hMCharmBuilding"), 7); if (std::fabs(xiccCand.pi2cDCAz()) < picMinDCAz) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 8); } + histos.fill(HIST("hMCharmBuilding"), 8); if (std::fabs(xiccCand.piccDCAxy()) < piccMinDCAxy) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 9); } + histos.fill(HIST("hMCharmBuilding"), 9); if (std::fabs(xiccCand.piccDCAz()) < piccMinDCAz) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 10); } + histos.fill(HIST("hMCharmBuilding"), 10); if (std::fabs(xiccCand.xicDCAxy()) < xicMinDCAxy) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 11); } + histos.fill(HIST("hMCharmBuilding"), 11); if (std::fabs(xiccCand.xicDCAz()) < xicMinDCAz) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 12); } + histos.fill(HIST("hMCharmBuilding"), 12); if (std::fabs(xiccCand.xiccDCAxy()) > xiccMaxDCAxy) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 13); } + histos.fill(HIST("hMCharmBuilding"), 13); if (std::fabs(xiccCand.xiccDCAz()) > xiccMaxDCAz) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 14); } + histos.fill(HIST("hMCharmBuilding"), 14); if (xiccCand.xicDecayRadius2D() < xicMinRadius) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 15); } + histos.fill(HIST("hMCharmBuilding"), 15); if (xiccCand.xiccDecayRadius2D() < xiccMinRadius) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 16); } + histos.fill(HIST("hMCharmBuilding"), 16); if (xiccCand.xicProperLength() < xicMinProperLength) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 17); } + histos.fill(HIST("hMCharmBuilding"), 17); if (xiccCand.xicProperLength() > xicMaxProperLength) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 18); } + histos.fill(HIST("hMCharmBuilding"), 18); if (xiccCand.xiccProperLength() < xiccMinProperLength) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 19); } + histos.fill(HIST("hMCharmBuilding"), 19); if (xiccCand.xiccProperLength() > xiccMaxProperLength) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 20); } + histos.fill(HIST("hMCharmBuilding"), 20); if (xiccCand.xicDistanceFromPV() < xicMinDecayDistanceFromPV) { continue; - } else { - histos.fill(HIST("hMCharmBuilding"), 21); } - histos.fill(HIST("SelectionQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * 1e+4); - histos.fill(HIST("SelectionQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * 1e+4); - histos.fill(HIST("SelectionQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * 1e+4)); - histos.fill(HIST("SelectionQA/hDCAzXi"), std::fabs(xiccCand.xiDCAz() * 1e+4)); - histos.fill(HIST("SelectionQA/hDCAxyXic"), std::fabs(xiccCand.xicDCAxy() * 1e+4)); - histos.fill(HIST("SelectionQA/hDCAzXic"), std::fabs(xiccCand.xicDCAz() * 1e+4)); - histos.fill(HIST("SelectionQA/hDCAxyXicc"), std::fabs(xiccCand.xiccDCAxy() * 1e+4)); - histos.fill(HIST("SelectionQA/hDCAzXicc"), std::fabs(xiccCand.xiccDCAz() * 1e+4)); - histos.fill(HIST("SelectionQA/hDecayRadiusXic"), xiccCand.xicDecayRadius2D() * 1e+4); - histos.fill(HIST("SelectionQA/hDecayRadiusXicc"), xiccCand.xiccDecayRadius2D() * 1e+4); - histos.fill(HIST("SelectionQA/hDecayDistanceFromPVXic"), xiccCand.xicDistanceFromPV() * 1e+4); - histos.fill(HIST("SelectionQA/hProperLengthXic"), xiccCand.xicProperLength() * 1e+4); - histos.fill(HIST("SelectionQA/hProperLengthXicc"), xiccCand.xiccProperLength() * 1e+4); - histos.fill(HIST("SelectionQA/hPi1cDCAxy"), xiccCand.pi1cDCAxy() * 1e+4); - histos.fill(HIST("SelectionQA/hPi1cDCAz"), xiccCand.pi1cDCAz() * 1e+4); - histos.fill(HIST("SelectionQA/hPi2cDCAxy"), xiccCand.pi2cDCAxy() * 1e+4); - histos.fill(HIST("SelectionQA/hPi2cDCAz"), xiccCand.pi2cDCAz() * 1e+4); - histos.fill(HIST("SelectionQA/hPiccDCAxy"), xiccCand.piccDCAxy() * 1e+4); - histos.fill(HIST("SelectionQA/hPiccDCAz"), xiccCand.piccDCAz() * 1e+4); + histos.fill(HIST("hMCharmBuilding"), 21); + histos.fill(HIST("SelectionQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * ToMicrons); + histos.fill(HIST("SelectionQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * ToMicrons); + histos.fill(HIST("SelectionQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * ToMicrons)); + histos.fill(HIST("SelectionQA/hDCAzXi"), std::fabs(xiccCand.xiDCAz() * ToMicrons)); + histos.fill(HIST("SelectionQA/hDCAxyXic"), std::fabs(xiccCand.xicDCAxy() * ToMicrons)); + histos.fill(HIST("SelectionQA/hDCAzXic"), std::fabs(xiccCand.xicDCAz() * ToMicrons)); + histos.fill(HIST("SelectionQA/hDCAxyXicc"), std::fabs(xiccCand.xiccDCAxy() * ToMicrons)); + histos.fill(HIST("SelectionQA/hDCAzXicc"), std::fabs(xiccCand.xiccDCAz() * ToMicrons)); + histos.fill(HIST("SelectionQA/hDecayRadiusXic"), xiccCand.xicDecayRadius2D() * ToMicrons); + histos.fill(HIST("SelectionQA/hDecayRadiusXicc"), xiccCand.xiccDecayRadius2D() * ToMicrons); + histos.fill(HIST("SelectionQA/hDecayDistanceFromPVXic"), xiccCand.xicDistanceFromPV() * ToMicrons); + histos.fill(HIST("SelectionQA/hProperLengthXic"), xiccCand.xicProperLength() * ToMicrons); + histos.fill(HIST("SelectionQA/hProperLengthXicc"), xiccCand.xiccProperLength() * ToMicrons); + histos.fill(HIST("SelectionQA/hPi1cDCAxy"), xiccCand.pi1cDCAxy() * ToMicrons); + histos.fill(HIST("SelectionQA/hPi1cDCAz"), xiccCand.pi1cDCAz() * ToMicrons); + histos.fill(HIST("SelectionQA/hPi2cDCAxy"), xiccCand.pi2cDCAxy() * ToMicrons); + histos.fill(HIST("SelectionQA/hPi2cDCAz"), xiccCand.pi2cDCAz() * ToMicrons); + histos.fill(HIST("SelectionQA/hPiccDCAxy"), xiccCand.piccDCAxy() * ToMicrons); + histos.fill(HIST("SelectionQA/hPiccDCAz"), xiccCand.piccDCAz() * ToMicrons); histos.fill(HIST("SelectionQA/hPi1cPt"), xiccCand.pi1cPt()); histos.fill(HIST("SelectionQA/hPi2cPt"), xiccCand.pi2cPt()); histos.fill(HIST("SelectionQA/hPiccPt"), xiccCand.piccPt()); - - if constexpr (requires { xiccCand.negPt(); }) { // if extra table - histos.fill(HIST("XiccProngs/h3dNeg"), xiccCand.xiccPt(), xiccCand.negPt(), xiccCand.negEta()); - histos.fill(HIST("XiccProngs/h3dPos"), xiccCand.xiccPt(), xiccCand.posPt(), xiccCand.posEta()); - histos.fill(HIST("XiccProngs/h3dBach"), xiccCand.xiccPt(), xiccCand.bachPt(), xiccCand.bachEta()); - histos.fill(HIST("XiccProngs/h3dPi1c"), xiccCand.xiccPt(), xiccCand.pi1cPt(), xiccCand.pi1cEta()); - histos.fill(HIST("XiccProngs/h3dPi2c"), xiccCand.xiccPt(), xiccCand.pi2cPt(), xiccCand.pi2cEta()); - histos.fill(HIST("XiccProngs/h3dPicc"), xiccCand.xiccPt(), xiccCand.piccPt(), xiccCand.piccEta()); - } - histos.fill(HIST("hXiccMass"), xiccCand.xiccMass()); histos.fill(HIST("hXicMass"), xiccCand.xicMass()); histos.fill(HIST("hXiccPt"), xiccCand.xiccPt()); @@ -520,13 +476,7 @@ struct Alice3Multicharm { genericProcessXicc(multiCharmTracks); } - void processXiccExtra(soa::Filtered const& multiCharmTracks) - { - genericProcessXicc(multiCharmTracks); - } - PROCESS_SWITCH(Alice3Multicharm, processXicc, "find Xicc baryons", true); - PROCESS_SWITCH(Alice3Multicharm, processXiccExtra, "find Xicc baryons with all QA", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)