diff --git a/ALICE3/Core/DetLayer.h b/ALICE3/Core/DetLayer.h index 7fa6aa25a53..6b9fea14c06 100644 --- a/ALICE3/Core/DetLayer.h +++ b/ALICE3/Core/DetLayer.h @@ -42,6 +42,9 @@ struct DetLayer { // efficiency float eff; // detection efficiency + + // layer type + int type; // 0: undefined/inert, 1: silicon, 2: gas/tpc }; } // namespace o2::fastsim diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index 25acbba4af5..715ed9343e2 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -30,13 +30,18 @@ FastTracker::FastTracker() applyZacceptance = false; covMatFactor = 0.99f; verboseLevel = 0; + + // last fast-tracked track properties covMatOK = 0; covMatNotOK = 0; + nIntercepts = 0; + nSiliconPoints = 0; + nGasPoints = 0; } -void FastTracker::AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi, float resZ, float eff) +void FastTracker::AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi, float resZ, float eff, int type) { - DetLayer newLayer{name.Data(), r, z, x0, xrho, resRPhi, resZ, eff}; + DetLayer newLayer{name.Data(), r, z, x0, xrho, resRPhi, resZ, eff, type}; layers.push_back(newLayer); } @@ -66,18 +71,18 @@ void FastTracker::AddSiliconALICE3v4() float resZOT = 0.0005; // 5 mum float eff = 1.00; - layers.push_back(DetLayer{"bpipe0", 0.48, 250, 0.00042, 2.772e-02, 0.0f, 0.0f, 0.0f}); // 150 mum Be - layers.push_back(DetLayer{"ddd0", 0.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff}); - layers.push_back(DetLayer{"ddd1", 1.2, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff}); - layers.push_back(DetLayer{"ddd2", 2.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff}); - layers.push_back(DetLayer{"bpipe1", 5.7, 250, 0.0014, 9.24e-02, 0.0f, 0.0f, 0.0f}); // 500 mum Be - layers.push_back(DetLayer{"ddd3", 7., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"ddd4", 10., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"ddd5", 13., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"ddd6", 16., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"ddd7", 25., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"ddd8", 40., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"ddd9", 45., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); + layers.push_back(DetLayer{"bpipe0", 0.48, 250, 0.00042, 2.772e-02, 0.0f, 0.0f, 0.0f, 0}); // 150 mum Be + layers.push_back(DetLayer{"ddd0", 0.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1}); + layers.push_back(DetLayer{"ddd1", 1.2, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1}); + layers.push_back(DetLayer{"ddd2", 2.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1}); + layers.push_back(DetLayer{"bpipe1", 5.7, 250, 0.0014, 9.24e-02, 0.0f, 0.0f, 0.0f, 0}); // 500 mum Be + layers.push_back(DetLayer{"ddd3", 7., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"ddd4", 10., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"ddd5", 13., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"ddd6", 16., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"ddd7", 25., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"ddd8", 40., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"ddd9", 45., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); } void FastTracker::AddSiliconALICE3v1() @@ -94,19 +99,19 @@ void FastTracker::AddSiliconALICE3v1() float resZOT = 0.00100; // 5 mum float eff = 1.00; - layers.push_back(DetLayer{"bpipe0", 0.48, 250, 0.00042, 2.772e-02, 0.0f, 0.0f, 0.0f}); // 150 mum Be - layers.push_back(DetLayer{"B00", 0.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff}); - layers.push_back(DetLayer{"B01", 1.2, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff}); - layers.push_back(DetLayer{"B02", 2.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff}); - layers.push_back(DetLayer{"bpipe1", 3.7, 250, 0.0014, 9.24e-02, 0.0f, 0.0f, 0.0f}); // 500 mum Be - layers.push_back(DetLayer{"B03", 3.75, 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B04", 7., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B05", 12., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B06", 20., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B07", 30., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B08", 45., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B09", 60., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); - layers.push_back(DetLayer{"B10", 80., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff}); + layers.push_back(DetLayer{"bpipe0", 0.48, 250, 0.00042, 2.772e-02, 0.0f, 0.0f, 0.0f, 1}); // 150 mum Be + layers.push_back(DetLayer{"B00", 0.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1}); + layers.push_back(DetLayer{"B01", 1.2, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1}); + layers.push_back(DetLayer{"B02", 2.5, 250, x0IT, xrhoIB, resRPhiIT, resZIT, eff, 1}); + layers.push_back(DetLayer{"bpipe1", 3.7, 250, 0.0014, 9.24e-02, 0.0f, 0.0f, 0.0f, 1}); // 500 mum Be + layers.push_back(DetLayer{"B03", 3.75, 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B04", 7., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B05", 12., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B06", 20., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B07", 30., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B08", 45., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B09", 60., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); + layers.push_back(DetLayer{"B10", 80., 250, x0OT, xrhoOB, resRPhiOT, resZOT, eff, 1}); } void FastTracker::AddTPC(float phiResMean, float zResMean) @@ -139,7 +144,7 @@ void FastTracker::AddTPC(float phiResMean, float zResMean) // add boundaries between ITS and TPC for (int i = 0; i < kNPassiveBound; i++) { - AddLayer(Form("tpc_boundary%d", i), rBoundary[i], zLength, radLBoundary[i], xrhoBoundary[i]); // dummy errors + AddLayer(Form("tpc_boundary%d", i), rBoundary[i], zLength, radLBoundary[i], xrhoBoundary[i], 0); // dummy errors } for (Int_t k = 0; k < tpcRows; k++) { Float_t rowRadius = 0; @@ -150,7 +155,7 @@ void FastTracker::AddTPC(float phiResMean, float zResMean) else if (k >= (innerRows + middleRows) && k < tpcRows) rowRadius = row128Radius + (k - innerRows - middleRows + 1) * tpcOuterRadialPitch; - AddLayer(Form("tpc_%d", k), rowRadius, zLength, radLPerRow, 0, phiResMean, zResMean, 1.0f); + AddLayer(Form("tpc_%d", k), rowRadius, zLength, radLPerRow, 0, phiResMean, zResMean, 1.0f, 2); } } @@ -159,7 +164,9 @@ void FastTracker::AddTPC(float phiResMean, float zResMean) int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackParCov& outputTrack) { hits.clear(); - int nIntercepts = 0; + nIntercepts = 0; + nSiliconPoints = 0; + nGasPoints = 0; std::array posIni; // provision for != PV inputTrack.getXYZGlo(posIni); float initialRadius = std::hypot(posIni[0], posIni[1]); @@ -172,7 +179,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa // check if layer is doable if (layers[il].r < initialRadius) continue; // this layer should not be attempted, but go ahead - if (layers[il].eff < 1e-5) + if (layers[il].type == 0) continue; // inert layer, skip // check if layer is reached @@ -240,6 +247,9 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa // +-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+ // Inward pass to calculate covariances for (int il = lastLayerReached; il >= firstLayerReached; il--) { + if (layers[il].type == 0) + continue; // inert layer, skip + float targetX = 1e+3; inputTrack.getXatLabR(layers[il].r, targetX, magneticField); if (targetX > 999) @@ -271,9 +281,14 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa static_cast(xyz1[2])}; const o2::track::TrackParametrization::dim3_t hitpointcov = {layers[il].resRPhi * layers[il].resRPhi, 0.f, layers[il].resZ * layers[il].resZ}; outputTrack.update(hitpoint, hitpointcov); + outputTrack.checkCovariance(); + + if (layers[il].type == 1) + nSiliconPoints++; // count silicon hits + if (layers[il].type == 2) + nGasPoints++; // count TPC/gas hits hits.push_back(thisHit); - outputTrack.checkCovariance(); } // backpropagate to original radius diff --git a/ALICE3/Core/FastTracker.h b/ALICE3/Core/FastTracker.h index e8ee7f500e6..ecd7d19cb98 100644 --- a/ALICE3/Core/FastTracker.h +++ b/ALICE3/Core/FastTracker.h @@ -34,7 +34,7 @@ class FastTracker FastTracker(); virtual ~FastTracker() {} - void AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi = 0.0f, float resZ = 0.0f, float eff = 0.0f); + void AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi = 0.0f, float resZ = 0.0f, float eff = 0.0f, int type = 0); void AddSiliconALICE3v4(); void AddSiliconALICE3v1(); @@ -56,6 +56,11 @@ class FastTracker uint64_t covMatOK; // cov mat has negative eigenvals uint64_t covMatNotOK; // cov mat has negative eigenvals + // last track information + int nIntercepts; // found in first outward propagation + int nSiliconPoints; // silicon-based space points added to track + int nGasPoints; // tpc-based space points added to track + ClassDef(FastTracker, 1); }; diff --git a/ALICE3/DataModel/OTFMulticharm.h b/ALICE3/DataModel/OTFMulticharm.h index 021288c0426..25bee30c717 100644 --- a/ALICE3/DataModel/OTFMulticharm.h +++ b/ALICE3/DataModel/OTFMulticharm.h @@ -38,19 +38,25 @@ DECLARE_SOA_COLUMN(DCAXiCCDaughters, dcaXiCCDaughters, float); DECLARE_SOA_COLUMN(MXiC, mXiC, float); DECLARE_SOA_COLUMN(MXiCC, mXiCC, float); +// kine vars +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Eta, eta, float); + } // namespace otfmulticharm -DECLARE_SOA_TABLE(MultiCharmStates, "AOD", "MultiCharmStates", +DECLARE_SOA_TABLE(MCharmIndices, "AOD", "MCharmIndices", o2::soa::Index<>, - otfcascade::CascadeId, - otfcascade::XiCPion1Id, - otfcascade::XiCPion2Id, - otfcascade::XiCCPionId, - otfcascade::DCAXiCDaughters, - otfcascade::DCAXiCCDaughters, - otfcascade::MXiC, - otfcascade::MXiCC); - -using MultiCharmState = MultiCharmState::iterator; + otfmulticharm::CascadeId, + otfmulticharm::XiCPion1Id, + otfmulticharm::XiCPion2Id, + otfmulticharm::XiCCPionId); + +DECLARE_SOA_TABLE(MCharmCores, "AOD", "MCharmCores", + otfmulticharm::DCAXiCDaughters, + otfmulticharm::DCAXiCCDaughters, + otfmulticharm::MXiC, + otfmulticharm::MXiCC, + otfmulticharm::Pt, + otfmulticharm::Eta); } // namespace o2::aod diff --git a/ALICE3/DataModel/tracksAlice3.h b/ALICE3/DataModel/tracksAlice3.h index c3a3e82a994..280c5ccb110 100644 --- a/ALICE3/DataModel/tracksAlice3.h +++ b/ALICE3/DataModel/tracksAlice3.h @@ -27,12 +27,18 @@ namespace o2::aod namespace track_alice3 { 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 } // namespace track_alice3 DECLARE_SOA_TABLE(TracksAlice3, "AOD", "TRACKSALICE3", track_alice3::IsReconstructed); - using TrackAlice3 = TracksAlice3::iterator; +DECLARE_SOA_TABLE(TracksExtraA3, "AOD", "TracksExtraA3", + track_alice3::NSiliconHits, + track_alice3::NTPCHits); +using TrackExtraA3 = TracksExtraA3::iterator; + } // namespace o2::aod #endif // ALICE3_DATAMODEL_TRACKSALICE3_H_ diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 9ee71307610..e602a602e1b 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -77,6 +77,7 @@ struct OnTheFlyTracker { Produces tracksDCACov; Produces collisionsAlice3; Produces TracksAlice3; + Produces TracksExtraA3; Produces upgradeCascades; // optionally produced, empty (to be tuned later) @@ -141,6 +142,8 @@ struct OnTheFlyTracker { struct : ConfigurableGroup { std::string prefix = "fastTrackerSettings"; // JSON group name Configurable minSiliconHits{"minSiliconHits", 4, "minimum number of silicon hits to accept track"}; + Configurable minSiliconHitsIfTPCUsed{"minSiliconHitsIfTPCUsed", 2, "minimum number of silicon hits to accept track in case TPC info is present"}; + Configurable minTPCClusters{"minTPCClusters", 70, "minimum number of TPC hits necessary to consider minSiliconHitsIfTPCUsed"}; Configurable alice3detector{"alice3detector", 0, "0: ALICE 3 v1, 1: ALICE 3 v4"}; Configurable applyZacceptance{"applyZacceptance", false, "apply z limits to detector layers or not"}; } fastTrackerSettings; // allows for gap between peak and bg in case someone wants to @@ -162,18 +165,29 @@ struct OnTheFlyTracker { TrackAlice3() = default; ~TrackAlice3() = default; TrackAlice3(const TrackAlice3& src) = default; - TrackAlice3(const o2::track::TrackParCov& src, const int64_t label, const float t = 0, const float te = 1, bool decayDauInput = false, bool weakDecayDauInput = false, int isUsedInCascadingInput = 0) : o2::track::TrackParCov(src), - mcLabel{label}, - timeEst{t, te}, - isDecayDau(decayDauInput), - isWeakDecayDau(weakDecayDauInput), - isUsedInCascading(isUsedInCascadingInput) {} + TrackAlice3(const o2::track::TrackParCov& src, const int64_t label, + const float t = 0, + const float te = 1, + bool decayDauInput = false, + bool weakDecayDauInput = false, + int isUsedInCascadingInput = 0, + int nSiliconHitsInput = 0, + int nTPCHitsInput = 0) : o2::track::TrackParCov(src), + mcLabel{label}, + timeEst{t, te}, + isDecayDau(decayDauInput), + isWeakDecayDau(weakDecayDauInput), + isUsedInCascading(isUsedInCascadingInput), + nSiliconHits(nSiliconHitsInput), + nTPCHits(nTPCHitsInput) {} const TimeEst& getTimeMUS() const { return timeEst; } int64_t mcLabel; TimeEst timeEst; ///< time estimate in ns bool isDecayDau; bool isWeakDecayDau; int isUsedInCascading; // 0: not at all, 1: is a cascade, 2: is a bachelor, 3: is a pion, 4: is a proton + int nSiliconHits; + int nTPCHits; }; // Helper struct to pass cascade information @@ -622,7 +636,9 @@ struct OnTheFlyTracker { std::vector xiDaughterTrackParCovsPerfect(3); std::vector xiDaughterTrackParCovsTracked(3); std::vector isReco(3); - std::vector nHits(3); + std::vector nHits(3); // total + std::vector nSiliconHits(3); // silicon type + std::vector nTPCHits(3); // TPC type std::vector smearer = {mSmearer0, mSmearer1, mSmearer2, mSmearer3, mSmearer4, mSmearer5}; if (treatXi && mcParticle.pdgCode() == 3312) { histos.fill(HIST("hXiBuilding"), 0.0f); @@ -636,11 +652,16 @@ struct OnTheFlyTracker { for (int i = 0; i < 3; i++) { isReco[i] = false; + nHits[i] = 0; + nSiliconHits[i] = 0; + nTPCHits[i] = 0; if (enableSecondarySmearing) { nHits[i] = fastTracker.FastTrack(xiDaughterTrackParCovsPerfect[i], xiDaughterTrackParCovsTracked[i]); + nSiliconHits[i] = fastTracker.nSiliconPoints; + nTPCHits[i] = fastTracker.nGasPoints; - if (nHits[i] >= fastTrackerSettings.minSiliconHits) { + if (nSiliconHits[i] >= fastTrackerSettings.minSiliconHits || (nSiliconHits[i] >= fastTrackerSettings.minSiliconHitsIfTPCUsed && nTPCHits[i] >= fastTrackerSettings.minTPCClusters)) { isReco[i] = true; } else { continue; // extra sure @@ -659,7 +680,7 @@ struct OnTheFlyTracker { histos.fill(HIST("hNaNBookkeeping"), i + 1, 1.0f); } if (isReco[i]) { - tracksAlice3.push_back(TrackAlice3{xiDaughterTrackParCovsTracked[i], mcParticle.globalIndex(), t, 100.f * 1e-3, true, true, i + 2}); + tracksAlice3.push_back(TrackAlice3{xiDaughterTrackParCovsTracked[i], mcParticle.globalIndex(), t, 100.f * 1e-3, true, true, i + 2, nSiliconHits[i], nTPCHits[i]}); } else { ghostTracksAlice3.push_back(TrackAlice3{xiDaughterTrackParCovsTracked[i], mcParticle.globalIndex(), t, 100.f * 1e-3, true, true, i + 2}); } @@ -1016,6 +1037,7 @@ struct OnTheFlyTracker { trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), trackParCov.getSigma1Pt2()); tracksLabels(trackParCov.mcLabel, 0); + TracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits); // populate extra tables if required to do so if (populateTracksExtra) { @@ -1063,6 +1085,7 @@ struct OnTheFlyTracker { trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), trackParCov.getSigma1Pt2()); tracksLabels(trackParCov.mcLabel, 0); + TracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits); // populate extra tables if required to do so if (populateTracksExtra) { diff --git a/ALICE3/TableProducer/alice3-multicharm.cxx b/ALICE3/TableProducer/alice3-multicharm.cxx index 7c996c01647..0c0f78d3701 100644 --- a/ALICE3/TableProducer/alice3-multicharm.cxx +++ b/ALICE3/TableProducer/alice3-multicharm.cxx @@ -47,6 +47,8 @@ #include "ALICE3/DataModel/RICH.h" #include "ALICE3/DataModel/A3DecayFinderTables.h" #include "ALICE3/DataModel/OTFStrangeness.h" +#include "ALICE3/DataModel/OTFMulticharm.h" +#include "ALICE3/DataModel/tracksAlice3.h" using namespace o2; using namespace o2::framework; @@ -64,11 +66,14 @@ using FullTracksExt = soa::Join; using labeledTracks = soa::Join; using tofTracks = soa::Join; using richTracks = soa::Join; -using alice3tracks = soa::Join; +using alice3tracks = soa::Join; struct alice3multicharm { SliceCache cache; + Produces multiCharmIdx; + Produces multiCharmCore; + // Operation and minimisation criteria Configurable magneticField{"magneticField", 20.0f, "Magnetic field (in kilogauss)"}; Configurable doDCAplots{"doDCAplots", true, "do daughter prong DCA plots for D mesons"}; @@ -83,7 +88,7 @@ struct alice3multicharm { Configurable xiFromXiC_dcaXYconstant{"xiFromXiC_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable xiFromXiC_dcaXYpTdep{"xiFromXiC_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; - ConfigurableAxis axisEta{"axisEta", {8, -4.0f, +4.0f}, "#eta"}; + ConfigurableAxis axisEta{"axisEta", {80, -4.0f, +4.0f}, "#eta"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; ConfigurableAxis axisDCA{"axisDCA", {200, -100, 100}, "DCA (#mum)"}; @@ -126,7 +131,18 @@ struct alice3multicharm { std::array prong1mom; std::array prong2mom; std::array parentTrackCovMatrix; - } thisCandidate; + } thisXiCcandidate; + + struct { + float dca; + float mass; + float pt; + float eta; + std::array xyz; + std::array prong0mom; + std::array prong1mom; + std::array parentTrackCovMatrix; + } thisXiCCcandidate; template bool buildDecayCandidateTwoBody(TTrackType const& t0, TTrackType const& t1, float mass0, float mass1) @@ -146,18 +162,18 @@ struct alice3multicharm { o2::track::TrackParCov t0new = fitter.getTrack(0); o2::track::TrackParCov t1new = fitter.getTrack(1); - t0new.getPxPyPzGlo(thisCandidate.prong0mom); - t1new.getPxPyPzGlo(thisCandidate.prong1mom); + t0new.getPxPyPzGlo(thisXiCCcandidate.prong0mom); + t1new.getPxPyPzGlo(thisXiCCcandidate.prong1mom); // get decay vertex coordinates const auto& vtx = fitter.getPCACandidate(); for (int i = 0; i < 3; i++) { - thisCandidate.xyz[i] = vtx[i]; + thisXiCCcandidate.xyz[i] = vtx[i]; } // compute cov mat for (int ii = 0; ii < 21; ii++) - thisCandidate.parentTrackCovMatrix[ii] = 0.0f; + thisXiCCcandidate.parentTrackCovMatrix[ii] = 0.0f; std::array covA = {0}; std::array covB = {0}; @@ -167,22 +183,22 @@ struct alice3multicharm { const int momInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component for (int i = 0; i < 6; i++) { int j = momInd[i]; - thisCandidate.parentTrackCovMatrix[j] = covA[j] + covB[j]; + thisXiCCcandidate.parentTrackCovMatrix[j] = covA[j] + covB[j]; } auto covVtx = fitter.calcPCACovMatrix(); - thisCandidate.parentTrackCovMatrix[0] = covVtx(0, 0); - thisCandidate.parentTrackCovMatrix[1] = covVtx(1, 0); - thisCandidate.parentTrackCovMatrix[2] = covVtx(1, 1); - thisCandidate.parentTrackCovMatrix[3] = covVtx(2, 0); - thisCandidate.parentTrackCovMatrix[4] = covVtx(2, 1); - thisCandidate.parentTrackCovMatrix[5] = covVtx(2, 2); + thisXiCCcandidate.parentTrackCovMatrix[0] = covVtx(0, 0); + thisXiCCcandidate.parentTrackCovMatrix[1] = covVtx(1, 0); + thisXiCCcandidate.parentTrackCovMatrix[2] = covVtx(1, 1); + thisXiCCcandidate.parentTrackCovMatrix[3] = covVtx(2, 0); + thisXiCCcandidate.parentTrackCovMatrix[4] = covVtx(2, 1); + thisXiCCcandidate.parentTrackCovMatrix[5] = covVtx(2, 2); // set relevant values - thisCandidate.dca = TMath::Sqrt(fitter.getChi2AtPCACandidate()); - thisCandidate.mass = RecoDecay::m(array{array{thisCandidate.prong0mom[0], thisCandidate.prong0mom[1], thisCandidate.prong0mom[2]}, array{thisCandidate.prong1mom[0], thisCandidate.prong1mom[1], thisCandidate.prong1mom[2]}}, array{mass0, mass1}); - thisCandidate.pt = std::hypot(thisCandidate.prong0mom[0] + thisCandidate.prong1mom[0], thisCandidate.prong0mom[1] + thisCandidate.prong1mom[1]); - thisCandidate.eta = RecoDecay::eta(array{thisCandidate.prong0mom[0] + thisCandidate.prong1mom[0], thisCandidate.prong0mom[1] + thisCandidate.prong1mom[1], thisCandidate.prong0mom[2] + thisCandidate.prong1mom[2]}); + thisXiCCcandidate.dca = TMath::Sqrt(fitter.getChi2AtPCACandidate()); + thisXiCCcandidate.mass = RecoDecay::m(array{array{thisXiCCcandidate.prong0mom[0], thisXiCCcandidate.prong0mom[1], thisXiCCcandidate.prong0mom[2]}, array{thisXiCCcandidate.prong1mom[0], thisXiCCcandidate.prong1mom[1], thisXiCCcandidate.prong1mom[2]}}, array{mass0, mass1}); + thisXiCCcandidate.pt = std::hypot(thisXiCCcandidate.prong0mom[0] + thisXiCCcandidate.prong1mom[0], thisXiCCcandidate.prong0mom[1] + thisXiCCcandidate.prong1mom[1]); + thisXiCCcandidate.eta = RecoDecay::eta(array{thisXiCCcandidate.prong0mom[0] + thisXiCCcandidate.prong1mom[0], thisXiCCcandidate.prong0mom[1] + thisXiCCcandidate.prong1mom[1], thisXiCCcandidate.prong0mom[2] + thisXiCCcandidate.prong1mom[2]}); return true; } @@ -209,19 +225,19 @@ struct alice3multicharm { t0 = fitter3.getTrack(0); t1 = fitter3.getTrack(1); t2 = fitter3.getTrack(2); - t0.getPxPyPzGlo(thisCandidate.prong0mom); - t1.getPxPyPzGlo(thisCandidate.prong1mom); - t2.getPxPyPzGlo(thisCandidate.prong2mom); + t0.getPxPyPzGlo(thisXiCcandidate.prong0mom); + t1.getPxPyPzGlo(thisXiCcandidate.prong1mom); + t2.getPxPyPzGlo(thisXiCcandidate.prong2mom); // get decay vertex coordinates const auto& vtx = fitter3.getPCACandidate(); for (int i = 0; i < 3; i++) { - thisCandidate.xyz[i] = vtx[i]; + thisXiCcandidate.xyz[i] = vtx[i]; } // compute cov mat for (int ii = 0; ii < 21; ii++) - thisCandidate.parentTrackCovMatrix[ii] = 0.0f; + thisXiCcandidate.parentTrackCovMatrix[ii] = 0.0f; std::array covA = {0}; std::array covB = {0}; @@ -233,22 +249,22 @@ struct alice3multicharm { const int momInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component for (int i = 0; i < 6; i++) { int j = momInd[i]; - thisCandidate.parentTrackCovMatrix[j] = covA[j] + covB[j] + covC[j]; + thisXiCcandidate.parentTrackCovMatrix[j] = covA[j] + covB[j] + covC[j]; } auto covVtx = fitter3.calcPCACovMatrix(); - thisCandidate.parentTrackCovMatrix[0] = covVtx(0, 0); - thisCandidate.parentTrackCovMatrix[1] = covVtx(1, 0); - thisCandidate.parentTrackCovMatrix[2] = covVtx(1, 1); - thisCandidate.parentTrackCovMatrix[3] = covVtx(2, 0); - thisCandidate.parentTrackCovMatrix[4] = covVtx(2, 1); - thisCandidate.parentTrackCovMatrix[5] = covVtx(2, 2); + thisXiCcandidate.parentTrackCovMatrix[0] = covVtx(0, 0); + thisXiCcandidate.parentTrackCovMatrix[1] = covVtx(1, 0); + thisXiCcandidate.parentTrackCovMatrix[2] = covVtx(1, 1); + thisXiCcandidate.parentTrackCovMatrix[3] = covVtx(2, 0); + thisXiCcandidate.parentTrackCovMatrix[4] = covVtx(2, 1); + thisXiCcandidate.parentTrackCovMatrix[5] = covVtx(2, 2); // set relevant values - thisCandidate.dca = TMath::Sqrt(fitter3.getChi2AtPCACandidate()); - thisCandidate.mass = RecoDecay::m(array{array{thisCandidate.prong0mom[0], thisCandidate.prong0mom[1], thisCandidate.prong0mom[2]}, array{thisCandidate.prong1mom[0], thisCandidate.prong1mom[1], thisCandidate.prong1mom[2]}, array{thisCandidate.prong2mom[0], thisCandidate.prong2mom[1], thisCandidate.prong2mom[2]}}, array{p0mass, p1mass, p2mass}); - thisCandidate.pt = std::hypot(thisCandidate.prong0mom[0] + thisCandidate.prong1mom[0] + thisCandidate.prong2mom[0], thisCandidate.prong0mom[1] + thisCandidate.prong1mom[1] + thisCandidate.prong2mom[1]); - thisCandidate.eta = RecoDecay::eta(array{thisCandidate.prong0mom[0] + thisCandidate.prong1mom[0] + thisCandidate.prong2mom[0], thisCandidate.prong0mom[1] + thisCandidate.prong1mom[1] + thisCandidate.prong2mom[1], thisCandidate.prong0mom[2] + thisCandidate.prong1mom[2] + thisCandidate.prong2mom[2]}); + thisXiCcandidate.dca = TMath::Sqrt(fitter3.getChi2AtPCACandidate()); + thisXiCcandidate.mass = RecoDecay::m(array{array{thisXiCcandidate.prong0mom[0], thisXiCcandidate.prong0mom[1], thisXiCcandidate.prong0mom[2]}, array{thisXiCcandidate.prong1mom[0], thisXiCcandidate.prong1mom[1], thisXiCcandidate.prong1mom[2]}, array{thisXiCcandidate.prong2mom[0], thisXiCcandidate.prong2mom[1], thisXiCcandidate.prong2mom[2]}}, array{p0mass, p1mass, p2mass}); + thisXiCcandidate.pt = std::hypot(thisXiCcandidate.prong0mom[0] + thisXiCcandidate.prong1mom[0] + thisXiCcandidate.prong2mom[0], thisXiCcandidate.prong0mom[1] + thisXiCcandidate.prong1mom[1] + thisXiCcandidate.prong2mom[1]); + thisXiCcandidate.eta = RecoDecay::eta(array{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]}); return true; } @@ -314,6 +330,10 @@ struct alice3multicharm { histos.add("hMassXiC", "hMassXiC", kTH1F, {axisXiCMass}); histos.add("hMassXiCC", "hMassXiCC", kTH1F, {axisXiCCMass}); + histos.add("hEtaXiCC", "hEtaXiCC", kTH1F, {axisEta}); + histos.add("hPtXiCC", "hPtXiCC", kTH1F, {axisPt}); + histos.add("h3dMassXiCC", "h3dMassXiCC", kTH3F, {axisPt, axisEta, axisXiCCMass}); + histos.add("hDCAXiCDaughters", "hDCAXiCDaughters", kTH1F, {axisDCAXiCDaughters}); histos.add("hDCAXiCCDaughters", "hDCAXiCCDaughters", kTH1F, {axisDCAXiCCDaughters}); @@ -398,14 +418,14 @@ struct alice3multicharm { histos.fill(HIST("hCharmBuilding"), 1.0f); const std::array momentumC = { - thisCandidate.prong0mom[0] + thisCandidate.prong1mom[0] + thisCandidate.prong2mom[0], - thisCandidate.prong0mom[1] + thisCandidate.prong1mom[1] + thisCandidate.prong2mom[1], - thisCandidate.prong0mom[2] + thisCandidate.prong1mom[2] + thisCandidate.prong2mom[2]}; + 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(thisCandidate.xyz, momentumC, thisCandidate.parentTrackCovMatrix, +1); + o2::track::TrackParCov xicTrack(thisXiCcandidate.xyz, momentumC, thisXiCcandidate.parentTrackCovMatrix, +1); - histos.fill(HIST("hMassXiC"), thisCandidate.mass); - histos.fill(HIST("hDCAXiCDaughters"), thisCandidate.dca); + histos.fill(HIST("hMassXiC"), thisXiCcandidate.mass); + histos.fill(HIST("hDCAXiCDaughters"), thisXiCcandidate.dca); // attempt XiCC finding uint32_t nCombinationsCC = 0; @@ -421,8 +441,17 @@ struct alice3multicharm { continue; // failed at building candidate histos.fill(HIST("hCharmBuilding"), 3.0f); - histos.fill(HIST("hMassXiCC"), thisCandidate.mass); - histos.fill(HIST("hDCAXiCCDaughters"), thisCandidate.dca); + histos.fill(HIST("hMassXiCC"), thisXiCCcandidate.mass); + histos.fill(HIST("hPtXiCC"), thisXiCCcandidate.pt); + histos.fill(HIST("hEtaXiCC"), thisXiCCcandidate.eta); + histos.fill(HIST("h3dMassXiCC"), thisXiCCcandidate.pt, thisXiCCcandidate.eta, thisXiCCcandidate.mass); + histos.fill(HIST("hDCAXiCCDaughters"), thisXiCCcandidate.dca); + + // produce multi-charm table for posterior analysis + multiCharmCore( + thisXiCcandidate.dca, thisXiCCcandidate.dca, + thisXiCcandidate.mass, thisXiCCcandidate.mass, + thisXiCCcandidate.pt, thisXiCCcandidate.eta); } histos.fill(HIST("hCombinationsXiCC"), nCombinationsCC); }